From 053ad04d3f50ec9bca40e48487e4a0cda9b320f4 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 18 Dec 2022 23:09:44 -0500 Subject: qt: continue event loop during game close --- src/yuzu/main.cpp | 64 +++++++++++++++++++++++++++++++--------- src/yuzu/main.h | 7 +++++ src/yuzu/util/overlay_dialog.cpp | 6 ++++ 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; -- cgit v1.2.3 From ae6015a69b211a98f9ef97d73b5c301c359ca35f Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 21 Dec 2022 19:27:11 -0500 Subject: qt: use main window as close overlay parent --- src/yuzu/main.cpp | 5 ++--- src/yuzu/util/overlay_dialog.cpp | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 66fdbcfed..c67fb997a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1815,9 +1815,8 @@ void GMainWindow::OnShutdownBegin() { } void GMainWindow::OnShutdownBeginDialog() { - shutdown_dialog = - new OverlayDialog(render_window, *system, QString{}, tr("Closing software..."), QString{}, - QString{}, Qt::AlignHCenter | Qt::AlignVCenter); + shutdown_dialog = new OverlayDialog(this, *system, QString{}, tr("Closing software..."), + QString{}, QString{}, Qt::AlignHCenter | Qt::AlignVCenter); shutdown_dialog->open(); } diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp index 25fa789ac..796f5bf41 100644 --- a/src/yuzu/util/overlay_dialog.cpp +++ b/src/yuzu/util/overlay_dialog.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "core/core.h" #include "core/hid/hid_types.h" @@ -162,7 +163,7 @@ void OverlayDialog::MoveAndResizeWindow() { const auto height = static_cast(parentWidget()->height()); // High DPI - const float dpi_scale = qApp->screenAt(pos)->logicalDotsPerInch() / 96.0f; + const float dpi_scale = parentWidget()->windowHandle()->screen()->logicalDotsPerInch() / 96.0f; const auto title_text_font_size = BASE_TITLE_FONT_SIZE * (height / BASE_HEIGHT) / dpi_scale; const auto body_text_font_size = -- cgit v1.2.3 From 646656412f71a554601173cac7a1d57af9a5232f Mon Sep 17 00:00:00 2001 From: Liam Date: Fri, 23 Dec 2022 20:57:36 -0500 Subject: qt: fix uninitialized memory usage --- src/yuzu/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/yuzu/main.h b/src/yuzu/main.h index ce1de17ef..95220b063 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -390,7 +390,7 @@ private: GameList* game_list; LoadingScreen* loading_screen; QTimer shutdown_timer; - OverlayDialog* shutdown_dialog; + OverlayDialog* shutdown_dialog{}; GameListPlaceholder* game_list_placeholder; -- cgit v1.2.3