mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2026-05-09 04:13:28 -05:00
Implement StopGame callback and use it to finish the emulation activity
This commit is contained in:
parent
fd21ca13ff
commit
b21cbc63f7
|
|
@ -44,6 +44,9 @@ object Netplay {
|
|||
private val _launchGame = Channel<String>(Channel.CONFLATED)
|
||||
val launchGame = _launchGame.receiveAsFlow()
|
||||
|
||||
private val _stopGame = Channel<Unit>(Channel.CONFLATED)
|
||||
val stopGame = _stopGame.receiveAsFlow()
|
||||
|
||||
private val _connectionErrors = Channel<String>(Channel.BUFFERED)
|
||||
val connectionErrors = _connectionErrors.receiveAsFlow()
|
||||
|
||||
|
|
@ -123,6 +126,7 @@ object Netplay {
|
|||
}
|
||||
|
||||
_launchGame.flush()
|
||||
_stopGame.flush()
|
||||
_connectionErrors.flush()
|
||||
_players.resetReplayCache()
|
||||
_messages.resetReplayCache()
|
||||
|
|
@ -166,9 +170,16 @@ object Netplay {
|
|||
@JvmStatic
|
||||
fun onBootGame(gameFilePath: String, bootSessionDataPointer: Long) {
|
||||
this.bootSessionDataPointer = bootSessionDataPointer
|
||||
_stopGame.flush()
|
||||
_launchGame.trySend(gameFilePath)
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun onStopGame() {
|
||||
_stopGame.trySend(Unit)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun onConnectionError(message: String) {
|
||||
_connectionErrors.trySend(message)
|
||||
|
|
@ -244,6 +255,6 @@ object Netplay {
|
|||
}
|
||||
}
|
||||
|
||||
private fun Channel<String>.flush() {
|
||||
private fun <T> Channel<T>.flush() {
|
||||
while (this.tryReceive().isSuccess) Unit
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import android.view.SurfaceHolder
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
||||
import org.dolphinemu.dolphinemu.databinding.FragmentEmulationBinding
|
||||
|
|
@ -220,6 +223,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
|||
val paths = requireNotNull(gamePaths) {
|
||||
"Cannot start emulation without any game paths"
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
Netplay.stopGame.first()
|
||||
stopEmulation()
|
||||
}
|
||||
NativeLibrary.RunNetPlay(paths, riivolution)
|
||||
} else {
|
||||
Log.debug("[EmulationFragment] Starting emulation thread.")
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ static jclass s_netplay_class;
|
|||
static jfieldID s_net_play_client_pointer;
|
||||
static jfieldID s_netplay_boot_session_data_pointer;
|
||||
static jmethodID s_netplay_on_boot_game;
|
||||
static jmethodID s_netplay_on_stop_game;
|
||||
static jmethodID s_netplay_on_connection_error;
|
||||
static jmethodID s_netplay_on_game_changed;
|
||||
static jmethodID s_netplay_on_host_input_authority_changed;
|
||||
|
|
@ -267,6 +268,11 @@ jmethodID GetNetplayOnBootGame()
|
|||
return s_netplay_on_boot_game;
|
||||
}
|
||||
|
||||
jmethodID GetNetplayOnStopGame()
|
||||
{
|
||||
return s_netplay_on_stop_game;
|
||||
}
|
||||
|
||||
jmethodID GetNetplayOnConnectionError()
|
||||
{
|
||||
return s_netplay_on_connection_error;
|
||||
|
|
@ -717,6 +723,7 @@ JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
|||
s_net_play_client_pointer = env->GetStaticFieldID(netplay_class, "netPlayClientPointer", "J");
|
||||
s_netplay_boot_session_data_pointer = env->GetStaticFieldID(netplay_class, "bootSessionDataPointer", "J");
|
||||
s_netplay_on_boot_game = env->GetStaticMethodID(netplay_class, "onBootGame", "(Ljava/lang/String;J)V");
|
||||
s_netplay_on_stop_game = env->GetStaticMethodID(netplay_class, "onStopGame", "()V");
|
||||
s_netplay_on_connection_error = env->GetStaticMethodID(netplay_class, "onConnectionError", "(Ljava/lang/String;)V");
|
||||
s_netplay_on_game_changed =
|
||||
env->GetStaticMethodID(netplay_class, "onGameChanged", "(Ljava/lang/String;)V");
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ jclass GetNetplayClass();
|
|||
jfieldID GetNetPlayClientPointer();
|
||||
jfieldID GetNetplayBootSessionDataPointer();
|
||||
jmethodID GetNetplayOnBootGame();
|
||||
jmethodID GetNetplayOnStopGame();
|
||||
jmethodID GetNetplayOnConnectionError();
|
||||
jmethodID GetNetplayOnGameChanged();
|
||||
jmethodID GetNetplayOnHostInputAuthorityChanged();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "UICommon/GameFile.h"
|
||||
#include "NetPlayUICallbacks.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Core.h"
|
||||
#include "jni/AndroidCommon/AndroidCommon.h"
|
||||
#include "jni/AndroidCommon/IDCache.h"
|
||||
|
||||
|
|
@ -12,17 +13,38 @@ namespace NetPlay {
|
|||
NetPlayUICallbacks::NetPlayUICallbacks(std::vector<std::shared_ptr<const UICommon::GameFile>> games)
|
||||
: m_games(std::move(games))
|
||||
{
|
||||
m_state_changed_hook = Core::AddOnStateChangedCallback([this](Core::State state) {
|
||||
if ((state == Core::State::Uninitialized || state == Core::State::Stopping) &&
|
||||
!m_got_stop_request)
|
||||
{
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
auto* client = reinterpret_cast<NetPlay::NetPlayClient*>(
|
||||
env->GetStaticLongField(IDCache::GetNetplayClass(), IDCache::GetNetPlayClientPointer()));
|
||||
if (client)
|
||||
client->RequestStopGame();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
NetPlayUICallbacks::~NetPlayUICallbacks() = default;
|
||||
|
||||
void NetPlayUICallbacks::BootGame(const std::string& filename, std::unique_ptr<BootSessionData> boot_session_data) {
|
||||
m_got_stop_request = false;
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
env->CallStaticVoidMethod(IDCache::GetNetplayClass(), IDCache::GetNetplayOnBootGame(),
|
||||
ToJString(env, filename), reinterpret_cast<jlong>(boot_session_data.release()));
|
||||
}
|
||||
|
||||
void NetPlayUICallbacks::StopGame() {}
|
||||
void NetPlayUICallbacks::StopGame()
|
||||
{
|
||||
if (m_got_stop_request)
|
||||
return;
|
||||
|
||||
m_got_stop_request = true;
|
||||
JNIEnv* env = IDCache::GetEnvForThread();
|
||||
env->CallStaticVoidMethod(IDCache::GetNetplayClass(), IDCache::GetNetplayOnStopGame());
|
||||
}
|
||||
|
||||
bool NetPlayUICallbacks::IsHosting() const { return false; }
|
||||
|
||||
void NetPlayUICallbacks::Update()
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/HookableEvent.h"
|
||||
#include "Core/NetPlayClient.h"
|
||||
#include "UICommon/GameFile.h"
|
||||
|
||||
|
|
@ -61,6 +62,8 @@ private:
|
|||
std::vector<std::shared_ptr<const UICommon::GameFile>> m_games;
|
||||
NetPlay::SyncIdentifier m_current_game_identifier;
|
||||
std::string m_current_game_name;
|
||||
Common::EventHook m_state_changed_hook;
|
||||
bool m_got_stop_request = true;
|
||||
};
|
||||
|
||||
} // namespace NetPlay
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user