summaryrefslogtreecommitdiff
path: root/Source/Android
diff options
context:
space:
mode:
authorTom Pratt <tom.pratt@outlook.com>2026-05-18 21:31:39 +0200
committerTom Pratt <tompratt@squareup.com>2026-05-19 12:03:02 +0200
commit4d1e74997749bca7744c1bbe78225e76f57a260c (patch)
tree39b3b03d66f6dc6ba893e1d01425ab64be917232 /Source/Android
parent06cc09cf09d27de28715a68e58fe8731bc311603 (diff)
WithSession helper function
Handles the repeated boiler plate of using a weak reference to NetplaySession from NetplayUICallbacks
Diffstat (limited to 'Source/Android')
-rw-r--r--Source/Android/jni/NetPlay/NetPlayUICallbacks.cpp321
-rw-r--r--Source/Android/jni/NetPlay/NetPlayUICallbacks.h12
2 files changed, 129 insertions, 204 deletions
diff --git a/Source/Android/jni/NetPlay/NetPlayUICallbacks.cpp b/Source/Android/jni/NetPlay/NetPlayUICallbacks.cpp
index 9f9c406846..de119b43c8 100644
--- a/Source/Android/jni/NetPlay/NetPlayUICallbacks.cpp
+++ b/Source/Android/jni/NetPlay/NetPlayUICallbacks.cpp
@@ -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;
-
- jintArray j_players = env->NewIntArray(static_cast<jsize>(players.size()));
- env->SetIntArrayRegion(j_players, 0, static_cast<jsize>(players.size()), players.data());
+ 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());
- 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) {}
diff --git a/Source/Android/jni/NetPlay/NetPlayUICallbacks.h b/Source/Android/jni/NetPlay/NetPlayUICallbacks.h
index 83ea2c06bc..602512e3b8 100644
--- a/Source/Android/jni/NetPlay/NetPlayUICallbacks.h
+++ b/Source/Android/jni/NetPlay/NetPlayUICallbacks.h
@@ -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;