mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-07-11 01:24:22 +02:00
WithSession helper function
Handles the repeated boiler plate of using a weak reference to NetplaySession from NetplayUICallbacks
This commit is contained in:
@@ -68,17 +68,12 @@ NetPlayUICallbacks::NetPlayUICallbacks(jobject netplay_session,
|
||||
if ((state == Core::State::Uninitialized || state == Core::State::Stopping) &&
|
||||
!m_got_stop_request)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(netplay_session, IDCache::GetNetPlayClientPointer()));
|
||||
if (client)
|
||||
client->RequestStopGame();
|
||||
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(session, IDCache::GetNetPlayClientPointer()));
|
||||
if (client)
|
||||
client->RequestStopGame();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -99,14 +94,10 @@ void NetPlayUICallbacks::BootGame(const std::string& filename,
|
||||
{
|
||||
m_got_stop_request = false;
|
||||
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnBootGame(), ToJString(env, filename),
|
||||
reinterpret_cast<jlong>(boot_session_data.release()));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnBootGame(), ToJString(env, filename),
|
||||
reinterpret_cast<jlong>(boot_session_data.release()));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::StopGame()
|
||||
@@ -116,13 +107,9 @@ void NetPlayUICallbacks::StopGame()
|
||||
|
||||
m_got_stop_request = true;
|
||||
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnStopGame());
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnStopGame());
|
||||
});
|
||||
}
|
||||
|
||||
// Only used by Qt UI code, never by the C++ core. On Android, hosting state
|
||||
@@ -131,56 +118,43 @@ bool NetPlayUICallbacks::IsHosting() const { return false; }
|
||||
|
||||
void NetPlayUICallbacks::Update()
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(session, IDCache::GetNetPlayClientPointer()));
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(netplay_session, IDCache::GetNetPlayClientPointer()));
|
||||
if (!client)
|
||||
{
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
return;
|
||||
}
|
||||
const std::vector<const NetPlay::Player*> players = client->GetPlayers();
|
||||
|
||||
const std::vector<const NetPlay::Player*> players = client->GetPlayers();
|
||||
jobjectArray player_array = env->NewObjectArray(
|
||||
static_cast<jsize>(players.size()), IDCache::GetNetplayPlayerClass(), nullptr);
|
||||
|
||||
jobjectArray player_array =
|
||||
env->NewObjectArray(static_cast<jsize>(players.size()), IDCache::GetNetplayPlayerClass(), nullptr);
|
||||
for (jsize i = 0; i < static_cast<jsize>(players.size()); i++)
|
||||
{
|
||||
const NetPlay::Player* player = players[i];
|
||||
const std::string mapping = NetPlay::GetPlayerMappingString(
|
||||
player->pid, client->GetPadMapping(), client->GetGBAConfig(),
|
||||
client->GetWiimoteMapping());
|
||||
jobject player_obj = env->NewObject(
|
||||
IDCache::GetNetplayPlayerClass(), IDCache::GetNetplayPlayerConstructor(),
|
||||
static_cast<jint>(player->pid), ToJString(env, player->name),
|
||||
ToJString(env, player->revision), static_cast<jint>(player->ping),
|
||||
static_cast<jboolean>(player->IsHost()), ToJString(env, mapping));
|
||||
env->SetObjectArrayElement(player_array, i, player_obj);
|
||||
env->DeleteLocalRef(player_obj);
|
||||
}
|
||||
|
||||
for (jsize i = 0; i < static_cast<jsize>(players.size()); i++)
|
||||
{
|
||||
const NetPlay::Player* player = players[i];
|
||||
const std::string mapping = NetPlay::GetPlayerMappingString(
|
||||
player->pid, client->GetPadMapping(), client->GetGBAConfig(), client->GetWiimoteMapping());
|
||||
jobject player_obj = env->NewObject(
|
||||
IDCache::GetNetplayPlayerClass(), IDCache::GetNetplayPlayerConstructor(),
|
||||
static_cast<jint>(player->pid),
|
||||
ToJString(env, player->name),
|
||||
ToJString(env, player->revision),
|
||||
static_cast<jint>(player->ping),
|
||||
static_cast<jboolean>(player->IsHost()),
|
||||
ToJString(env, mapping));
|
||||
env->SetObjectArrayElement(player_array, i, player_obj);
|
||||
env->DeleteLocalRef(player_obj);
|
||||
}
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayUpdate(), player_array);
|
||||
env->DeleteLocalRef(player_array);
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayUpdate(), player_array);
|
||||
env->DeleteLocalRef(player_array);
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::AppendChat(const std::string& message)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnChatMessageReceived(),
|
||||
ToJString(env, message));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnChatMessageReceived(),
|
||||
ToJString(env, message));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnMsgChangeGame(const NetPlay::SyncIdentifier& sync_identifier,
|
||||
@@ -189,34 +163,25 @@ void NetPlayUICallbacks::OnMsgChangeGame(const NetPlay::SyncIdentifier& sync_ide
|
||||
m_current_game_identifier = sync_identifier;
|
||||
m_current_game_name = netplay_name;
|
||||
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnGameChanged(),
|
||||
ToJString(env, netplay_name));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnGameChanged(),
|
||||
ToJString(env, netplay_name));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnMsgChangeGBARom(int, const NetPlay::GBAConfig&) {}
|
||||
|
||||
void NetPlayUICallbacks::OnMsgStartGame()
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(netplay_session, IDCache::GetNetPlayClientPointer()));
|
||||
if (client)
|
||||
{
|
||||
if (const auto game = FindGameFile(m_current_game_identifier))
|
||||
client->StartGame(game->GetFilePath());
|
||||
}
|
||||
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([this](JNIEnv* env, jobject session) {
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetLongField(session, IDCache::GetNetPlayClientPointer()));
|
||||
if (client)
|
||||
{
|
||||
if (const auto game = FindGameFile(m_current_game_identifier))
|
||||
client->StartGame(game->GetFilePath());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnMsgStopGame() {}
|
||||
@@ -232,61 +197,41 @@ void NetPlayUICallbacks::OnPlayerDisconnect(const std::string&) {}
|
||||
|
||||
void NetPlayUICallbacks::OnPadBufferChanged(u32 buffer)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnPadBufferChanged(),
|
||||
static_cast<jint>(buffer));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnPadBufferChanged(),
|
||||
static_cast<jint>(buffer));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnHostInputAuthorityChanged(bool enabled)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnHostInputAuthorityChanged(),
|
||||
static_cast<jboolean>(enabled));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnHostInputAuthorityChanged(),
|
||||
static_cast<jboolean>(enabled));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnDesync(u32 frame, const std::string& player)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnDesync(),
|
||||
static_cast<jint>(frame), ToJString(env, player));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnDesync(),
|
||||
static_cast<jint>(frame), ToJString(env, player));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnConnectionLost()
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnConnectionLost());
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnConnectionLost());
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnConnectionError(const std::string& message)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnConnectionError(),
|
||||
ToJString(env, message));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnConnectionError(),
|
||||
ToJString(env, message));
|
||||
});
|
||||
}
|
||||
|
||||
// No-op — all error info is captured by OnTraversalStateChanged which always fires alongside.
|
||||
@@ -294,17 +239,14 @@ void NetPlayUICallbacks::OnTraversalError(Common::TraversalClient::FailureReason
|
||||
|
||||
void NetPlayUICallbacks::OnTraversalStateChanged(Common::TraversalClient::State state)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
if (!Common::g_TraversalClient)
|
||||
return;
|
||||
|
||||
jstring host_code = nullptr;
|
||||
jstring external_address = nullptr;
|
||||
jstring failure_reason = nullptr;
|
||||
jstring host_code = nullptr;
|
||||
jstring external_address = nullptr;
|
||||
jstring failure_reason = nullptr;
|
||||
|
||||
if (Common::g_TraversalClient)
|
||||
{
|
||||
if (state == Common::TraversalClient::State::Connected)
|
||||
{
|
||||
const auto host_id = Common::g_TraversalClient->GetHostID();
|
||||
@@ -318,17 +260,16 @@ void NetPlayUICallbacks::OnTraversalStateChanged(Common::TraversalClient::State
|
||||
ToJString(env, FailureReasonToString(Common::g_TraversalClient->GetFailureReason()));
|
||||
}
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnTraversalStateChanged(),
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnTraversalStateChanged(),
|
||||
static_cast<jint>(state), host_code, external_address, failure_reason);
|
||||
}
|
||||
|
||||
if (host_code)
|
||||
env->DeleteLocalRef(host_code);
|
||||
if (external_address)
|
||||
env->DeleteLocalRef(external_address);
|
||||
if (failure_reason)
|
||||
env->DeleteLocalRef(failure_reason);
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
if (host_code)
|
||||
env->DeleteLocalRef(host_code);
|
||||
if (external_address)
|
||||
env->DeleteLocalRef(external_address);
|
||||
if (failure_reason)
|
||||
env->DeleteLocalRef(failure_reason);
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::OnGameStartAborted() {}
|
||||
@@ -365,89 +306,61 @@ std::string NetPlayUICallbacks::FindGBARomPath(const std::array<u8, 20>&, std::s
|
||||
|
||||
void NetPlayUICallbacks::ShowGameDigestDialog(const std::string& title)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnShowGameDigestDialog(),
|
||||
ToJString(env, title));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnShowGameDigestDialog(),
|
||||
ToJString(env, title));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::SetGameDigestProgress(int pid, int progress)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnSetGameDigestProgress(),
|
||||
static_cast<jint>(pid), static_cast<jint>(progress));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnSetGameDigestProgress(),
|
||||
static_cast<jint>(pid), static_cast<jint>(progress));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::SetGameDigestResult(int pid, const std::string& result)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnSetGameDigestResult(),
|
||||
static_cast<jint>(pid), ToJString(env, result));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnSetGameDigestResult(),
|
||||
static_cast<jint>(pid), ToJString(env, result));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::AbortGameDigest()
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnAbortGameDigest());
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnAbortGameDigest());
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::ShowChunkedProgressDialog(const std::string& title, u64 data_size,
|
||||
std::span<const int> players)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
jintArray j_players = env->NewIntArray(static_cast<jsize>(players.size()));
|
||||
env->SetIntArrayRegion(j_players, 0, static_cast<jsize>(players.size()), players.data());
|
||||
|
||||
jintArray j_players = env->NewIntArray(static_cast<jsize>(players.size()));
|
||||
env->SetIntArrayRegion(j_players, 0, static_cast<jsize>(players.size()), players.data());
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnShowChunkedProgressDialog(),
|
||||
ToJString(env, title), static_cast<jlong>(data_size), j_players);
|
||||
env->DeleteLocalRef(j_players);
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnShowChunkedProgressDialog(),
|
||||
ToJString(env, title), static_cast<jlong>(data_size), j_players);
|
||||
env->DeleteLocalRef(j_players);
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::HideChunkedProgressDialog()
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnHideChunkedProgressDialog());
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnHideChunkedProgressDialog());
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::SetChunkedProgress(int pid, u64 progress)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
|
||||
env->CallVoidMethod(netplay_session, IDCache::GetNetplayOnSetChunkedProgress(),
|
||||
static_cast<jint>(pid), static_cast<jlong>(progress));
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
WithSession([&](JNIEnv* env, jobject session) {
|
||||
env->CallVoidMethod(session, IDCache::GetNetplayOnSetChunkedProgress(),
|
||||
static_cast<jint>(pid), static_cast<jlong>(progress));
|
||||
});
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::SetHostWiiSyncData(std::vector<u64>, std::string) {}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Common/HookableEvent.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "UICommon/GameFile.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
|
||||
namespace NetPlay {
|
||||
|
||||
@@ -67,6 +68,17 @@ public:
|
||||
private:
|
||||
jobject GetNetplaySessionLocalRef(JNIEnv* env) const;
|
||||
|
||||
template <typename F>
|
||||
void WithSession(F&& callback) const
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
jobject netplay_session = GetNetplaySessionLocalRef(env);
|
||||
if (!netplay_session)
|
||||
return;
|
||||
callback(env, netplay_session);
|
||||
env->DeleteLocalRef(netplay_session);
|
||||
}
|
||||
|
||||
jweak m_netplay_session;
|
||||
std::vector<std::shared_ptr<const UICommon::GameFile>> m_games;
|
||||
NetPlay::SyncIdentifier m_current_game_identifier;
|
||||
|
||||
Reference in New Issue
Block a user