mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +00:00 
			
		
		
		
	Qt: Create emu thread on bootup, kill it on shutdown.
This commit is contained in:
		
							parent
							
								
									d5665fea89
								
							
						
					
					
						commit
						28df8dbfeb
					
				
					 3 changed files with 44 additions and 31 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue