diff options
author | Liam <byteslice@airmail.cc> | 2022-12-18 23:09:44 -0500 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2022-12-20 09:16:08 -0500 |
commit | 053ad04d3f50ec9bca40e48487e4a0cda9b320f4 (patch) | |
tree | 22bd63ff466f5a4c1b08c028f9b3cde18633bb94 /src/yuzu/main.cpp | |
parent | 1b11e0f0d3209603e67b26f3ef22f1d1a493bbdc (diff) |
qt: continue event loop during game close
Diffstat (limited to 'src/yuzu/main.cpp')
-rw-r--r-- | src/yuzu/main.cpp | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 820f60e61b..66fdbcfed9 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1550,8 +1550,9 @@ void GMainWindow::AllowOSSleep() { bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) { // Shutdown previous session if the emu thread is still active... - if (emu_thread != nullptr) + if (emu_thread != nullptr) { ShutdownGame(); + } if (!render_window->InitRenderTarget()) { return false; @@ -1779,7 +1780,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t OnStartGame(); } -void GMainWindow::ShutdownGame() { +void GMainWindow::OnShutdownBegin() { if (!emulation_running) { return; } @@ -1802,13 +1803,41 @@ void GMainWindow::ShutdownGame() { emit EmulationStopping(); - // Wait for emulation thread to complete and delete it - if (system->DebuggerEnabled() || !emu_thread->wait(5000)) { + shutdown_timer.setSingleShot(true); + shutdown_timer.start(system->DebuggerEnabled() ? 0 : 5000); + connect(&shutdown_timer, &QTimer::timeout, this, &GMainWindow::OnEmulationStopTimeExpired); + connect(emu_thread.get(), &QThread::finished, this, &GMainWindow::OnEmulationStopped); + + // Disable everything to prevent anything from being triggered here + ui->action_Pause->setEnabled(false); + ui->action_Restart->setEnabled(false); + ui->action_Stop->setEnabled(false); +} + +void GMainWindow::OnShutdownBeginDialog() { + shutdown_dialog = + new OverlayDialog(render_window, *system, QString{}, tr("Closing software..."), QString{}, + QString{}, Qt::AlignHCenter | Qt::AlignVCenter); + shutdown_dialog->open(); +} + +void GMainWindow::OnEmulationStopTimeExpired() { + if (emu_thread) { emu_thread->ForceStop(); - emu_thread->wait(); } +} + +void GMainWindow::OnEmulationStopped() { + shutdown_timer.stop(); + emu_thread->disconnect(); + emu_thread->wait(); emu_thread = nullptr; + if (shutdown_dialog) { + shutdown_dialog->deleteLater(); + shutdown_dialog = nullptr; + } + emulation_running = false; discord_rpc->Update(); @@ -1854,6 +1883,20 @@ void GMainWindow::ShutdownGame() { // When closing the game, destroy the GLWindow to clear the context after the game is closed render_window->ReleaseRenderTarget(); + + Settings::RestoreGlobalState(system->IsPoweredOn()); + system->HIDCore().ReloadInputDevices(); + UpdateStatusButtons(); +} + +void GMainWindow::ShutdownGame() { + if (!emulation_running) { + return; + } + + OnShutdownBegin(); + OnEmulationStopTimeExpired(); + OnEmulationStopped(); } void GMainWindow::StoreRecentFile(const QString& filename) { @@ -2956,11 +2999,8 @@ void GMainWindow::OnStopGame() { return; } - ShutdownGame(); - - Settings::RestoreGlobalState(system->IsPoweredOn()); - system->HIDCore().ReloadInputDevices(); - UpdateStatusButtons(); + OnShutdownBegin(); + OnShutdownBeginDialog(); } void GMainWindow::OnLoadComplete() { @@ -4047,10 +4087,6 @@ void GMainWindow::closeEvent(QCloseEvent* event) { // Shutdown session if the emu thread is active... if (emu_thread != nullptr) { ShutdownGame(); - - Settings::RestoreGlobalState(system->IsPoweredOn()); - system->HIDCore().ReloadInputDevices(); - UpdateStatusButtons(); } render_window->close(); |