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 | |
| parent | 1b11e0f0d3209603e67b26f3ef22f1d1a493bbdc (diff) | |
qt: continue event loop during game close
| -rw-r--r-- | src/yuzu/main.cpp | 64 | ||||
| -rw-r--r-- | src/yuzu/main.h | 7 | ||||
| -rw-r--r-- | src/yuzu/util/overlay_dialog.cpp | 6 | ||||
| -rw-r--r-- | src/yuzu/util/overlay_dialog.h | 1 | 
4 files changed, 64 insertions, 14 deletions
| diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 820f60e61..66fdbcfed 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(); diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 5b84c7a00..ce1de17ef 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -29,6 +29,7 @@ class GImageInfo;  class GRenderWindow;  class LoadingScreen;  class MicroProfileDialog; +class OverlayDialog;  class ProfilerWidget;  class ControllerDialog;  class QLabel; @@ -335,6 +336,10 @@ private slots:      void OnReinitializeKeys(ReinitializeKeyBehavior behavior);      void OnLanguageChanged(const QString& locale);      void OnMouseActivity(); +    void OnShutdownBegin(); +    void OnShutdownBeginDialog(); +    void OnEmulationStopped(); +    void OnEmulationStopTimeExpired();  private:      QString GetGameListErrorRemoving(InstalledEntryType type) const; @@ -384,6 +389,8 @@ private:      GRenderWindow* render_window;      GameList* game_list;      LoadingScreen* loading_screen; +    QTimer shutdown_timer; +    OverlayDialog* shutdown_dialog;      GameListPlaceholder* game_list_placeholder; diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp index 3fa3d0afb..25fa789ac 100644 --- a/src/yuzu/util/overlay_dialog.cpp +++ b/src/yuzu/util/overlay_dialog.cpp @@ -259,3 +259,9 @@ void OverlayDialog::InputThread() {          std::this_thread::sleep_for(std::chrono::milliseconds(50));      }  } + +void OverlayDialog::keyPressEvent(QKeyEvent* e) { +    if (!ui->buttonsDialog->isHidden() || e->key() != Qt::Key_Escape) { +        QDialog::keyPressEvent(e); +    } +} diff --git a/src/yuzu/util/overlay_dialog.h b/src/yuzu/util/overlay_dialog.h index 39c44393c..872283d61 100644 --- a/src/yuzu/util/overlay_dialog.h +++ b/src/yuzu/util/overlay_dialog.h @@ -94,6 +94,7 @@ private:      /// The thread where input is being polled and processed.      void InputThread(); +    void keyPressEvent(QKeyEvent* e) override;      std::unique_ptr<Ui::OverlayDialog> ui; | 
