mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Qt: Create emu thread on bootup, kill it on shutdown.
This commit is contained in:
		
							parent
							
								
									d5665fea89
								
							
						
					
					
						commit
						28df8dbfeb
					
				@ -30,21 +30,19 @@
 | 
			
		||||
EmuThread::EmuThread(GRenderWindow* render_window) :
 | 
			
		||||
    exec_cpu_step(false), cpu_running(false), stop_run(false), render_window(render_window) {
 | 
			
		||||
 | 
			
		||||
    shutdown_event.Reset();
 | 
			
		||||
    connect(this, SIGNAL(started()), render_window, SLOT(moveContext()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EmuThread::run()
 | 
			
		||||
{
 | 
			
		||||
void EmuThread::run() {
 | 
			
		||||
    stop_run = false;
 | 
			
		||||
 | 
			
		||||
    // holds whether the cpu was running during the last iteration,
 | 
			
		||||
    // so that the DebugModeLeft signal can be emitted before the
 | 
			
		||||
    // next execution step
 | 
			
		||||
    bool was_active = false;
 | 
			
		||||
    while (!stop_run)
 | 
			
		||||
    {
 | 
			
		||||
        if (cpu_running)
 | 
			
		||||
        {
 | 
			
		||||
    while (!stop_run) {
 | 
			
		||||
        if (cpu_running) {
 | 
			
		||||
            if (!was_active)
 | 
			
		||||
                emit DebugModeLeft();
 | 
			
		||||
 | 
			
		||||
@ -53,9 +51,7 @@ void EmuThread::run()
 | 
			
		||||
            was_active = cpu_running || exec_cpu_step;
 | 
			
		||||
            if (!was_active)
 | 
			
		||||
                emit DebugModeEntered();
 | 
			
		||||
        }
 | 
			
		||||
        else if (exec_cpu_step)
 | 
			
		||||
        {
 | 
			
		||||
        } else if (exec_cpu_step) {
 | 
			
		||||
            if (!was_active)
 | 
			
		||||
                emit DebugModeLeft();
 | 
			
		||||
 | 
			
		||||
@ -67,15 +63,14 @@ void EmuThread::run()
 | 
			
		||||
            was_active = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    render_window->moveContext();
 | 
			
		||||
 | 
			
		||||
    Core::Stop();
 | 
			
		||||
    shutdown_event.Set();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EmuThread::Stop()
 | 
			
		||||
{
 | 
			
		||||
    if (!isRunning())
 | 
			
		||||
    {
 | 
			
		||||
void EmuThread::Stop() {
 | 
			
		||||
    if (!isRunning()) {
 | 
			
		||||
        LOG_WARNING(Frontend, "EmuThread::Stop called while emu thread wasn't running, returning...");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
@ -88,23 +83,19 @@ void EmuThread::Stop()
 | 
			
		||||
 | 
			
		||||
    // TODO: Waiting here is just a bad workaround for retarded shutdown logic.
 | 
			
		||||
    wait(1000);
 | 
			
		||||
    if (isRunning())
 | 
			
		||||
    {
 | 
			
		||||
    if (isRunning()) {
 | 
			
		||||
        LOG_WARNING(Frontend, "EmuThread still running, terminating...");
 | 
			
		||||
        quit();
 | 
			
		||||
 | 
			
		||||
        // TODO: Waiting 50 seconds can be necessary if the logging subsystem has a lot of spam
 | 
			
		||||
        // queued... This should be fixed.
 | 
			
		||||
        wait(50000);
 | 
			
		||||
        if (isRunning())
 | 
			
		||||
        {
 | 
			
		||||
        if (isRunning()) {
 | 
			
		||||
            LOG_CRITICAL(Frontend, "EmuThread STILL running, something is wrong here...");
 | 
			
		||||
            terminate();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    LOG_INFO(Frontend, "EmuThread stopped");
 | 
			
		||||
 | 
			
		||||
    System::Shutdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,7 @@
 | 
			
		||||
 | 
			
		||||
#include "common/common.h"
 | 
			
		||||
#include "common/emu_window.h"
 | 
			
		||||
#include "common/thread.h"
 | 
			
		||||
 | 
			
		||||
class QScreen;
 | 
			
		||||
class QKeyEvent;
 | 
			
		||||
@ -37,20 +38,31 @@ public:
 | 
			
		||||
    void ExecStep() { exec_cpu_step = true; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Allow the CPU to continue processing instructions without interruption
 | 
			
		||||
     * Sets whether the CPU is running 
 | 
			
		||||
     *
 | 
			
		||||
     * @note This function is thread-safe
 | 
			
		||||
     */
 | 
			
		||||
    void SetCpuRunning(bool running) { cpu_running = running; }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
    * Allow the CPU to continue processing instructions without interruption
 | 
			
		||||
    *
 | 
			
		||||
    * @note This function is thread-safe
 | 
			
		||||
    */
 | 
			
		||||
     * Allow the CPU to continue processing instructions without interruption
 | 
			
		||||
     *
 | 
			
		||||
     * @note This function is thread-safe
 | 
			
		||||
     */
 | 
			
		||||
    bool IsCpuRunning() { return cpu_running; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Shutdown (permantently stops) the CPU
 | 
			
		||||
     */
 | 
			
		||||
    void ShutdownCpu() { stop_run = true; };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Waits for the CPU shutdown to complete
 | 
			
		||||
     */
 | 
			
		||||
    void WaitForCpuShutdown() { shutdown_event.Wait(); }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
    /**
 | 
			
		||||
     * Stop emulation and wait for the thread to finish.
 | 
			
		||||
@ -71,6 +83,8 @@ private:
 | 
			
		||||
 | 
			
		||||
    GRenderWindow* render_window;
 | 
			
		||||
 | 
			
		||||
    Common::Event shutdown_event;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    /**
 | 
			
		||||
     * Emitted when the CPU has halted execution
 | 
			
		||||
 | 
			
		||||
@ -57,7 +57,6 @@ GMainWindow::GMainWindow() : emu_thread(nullptr)
 | 
			
		||||
 | 
			
		||||
    render_window = new GRenderWindow(this, *this);
 | 
			
		||||
    render_window->hide();
 | 
			
		||||
    emu_thread = new EmuThread(render_window);
 | 
			
		||||
 | 
			
		||||
    profilerWidget = new ProfilerWidget(this);
 | 
			
		||||
    addDockWidget(Qt::BottomDockWidgetArea, profilerWidget);
 | 
			
		||||
@ -197,9 +196,9 @@ void GMainWindow::OnDisplayTitleBars(bool show)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::BootGame(std::string filename)
 | 
			
		||||
{
 | 
			
		||||
void GMainWindow::BootGame(std::string filename) {
 | 
			
		||||
    LOG_INFO(Frontend, "Citra starting...\n");
 | 
			
		||||
 | 
			
		||||
    System::Init(render_window);
 | 
			
		||||
 | 
			
		||||
    // Load a game or die...
 | 
			
		||||
@ -211,6 +210,7 @@ void GMainWindow::BootGame(std::string filename)
 | 
			
		||||
    registersWidget->OnDebugModeEntered();
 | 
			
		||||
    callstackWidget->OnDebugModeEntered();
 | 
			
		||||
 | 
			
		||||
    emu_thread = new EmuThread(render_window);
 | 
			
		||||
    emu_thread->start();
 | 
			
		||||
 | 
			
		||||
    render_window->show();
 | 
			
		||||
@ -248,14 +248,22 @@ void GMainWindow::OnPauseGame()
 | 
			
		||||
    ui.action_Stop->setEnabled(true);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::OnStopGame()
 | 
			
		||||
{
 | 
			
		||||
void GMainWindow::OnStopGame() {
 | 
			
		||||
    emu_thread->SetCpuRunning(false);
 | 
			
		||||
    // TODO: Shutdown core
 | 
			
		||||
 | 
			
		||||
    emu_thread->ShutdownCpu();
 | 
			
		||||
    emu_thread->WaitForCpuShutdown();
 | 
			
		||||
    emu_thread->Stop();
 | 
			
		||||
 | 
			
		||||
    delete emu_thread;
 | 
			
		||||
 | 
			
		||||
    System::Shutdown();
 | 
			
		||||
 | 
			
		||||
    ui.action_Start->setEnabled(true);
 | 
			
		||||
    ui.action_Pause->setEnabled(false);
 | 
			
		||||
    ui.action_Stop->setEnabled(false);
 | 
			
		||||
 | 
			
		||||
    render_window->hide();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void GMainWindow::OnOpenHotkeysDialog()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user