diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 60db83c98f..122289c5b0 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -24,6 +24,7 @@ #include "Common/Logging/LogManager.h" #include "Common/MemoryUtil.h" #include "Common/MsgHandler.h" +#include "Common/ScopeGuard.h" #include "Common/StringUtil.h" #include "Common/Thread.h" #include "Common/Timer.h" @@ -453,6 +454,19 @@ static void EmuThread() { const SConfig& core_parameter = SConfig::GetInstance(); s_is_booting.Set(); + Common::ScopeGuard flag_guard{[] { + s_is_booting.Clear(); + s_is_started = false; + s_is_stopping = false; + + if (s_on_stopped_callback) + s_on_stopped_callback(); + + INFO_LOG(CONSOLE, "Stop\t\t---- Shutdown complete ----"); + }}; + + // Prevent the UI from getting stuck whenever an error occurs. + Common::ScopeGuard stop_message_guard{[] { Host_Message(WM_USER_STOP); }}; Common::SetCurrentThreadName("Emuthread - Starting"); @@ -466,16 +480,23 @@ static void EmuThread() DeclareAsCPUThread(); Movie::Init(); + Common::ScopeGuard movie_guard{Movie::Shutdown}; HW::Init(); + Common::ScopeGuard hw_guard{[] { + // We must set up this flag before executing HW::Shutdown() + s_hardware_initialized = false; + INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); + HW::Shutdown(); + INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); + }}; if (!g_video_backend->Initialize(s_window_handle)) { - s_is_booting.Clear(); PanicAlert("Failed to initialize video backend!"); - Host_Message(WM_USER_STOP); return; } + Common::ScopeGuard video_guard{[] { g_video_backend->Shutdown(); }}; OSD::AddMessage("Dolphin " + g_video_backend->GetName() + " Video Backend.", 5000); @@ -486,11 +507,7 @@ static void EmuThread() if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, core_parameter.bDSPThread)) { - s_is_booting.Clear(); - HW::Shutdown(); - g_video_backend->Shutdown(); PanicAlert("Failed to initialize DSP emulation!"); - Host_Message(WM_USER_STOP); return; } @@ -520,7 +537,18 @@ static void EmuThread() Wiimote::LoadConfig(); } + Common::ScopeGuard controller_guard{[init_controllers] { + if (!init_controllers) + return; + + Wiimote::Shutdown(); + Keyboard::Shutdown(); + Pad::Shutdown(); + g_controller_interface.Shutdown(); + }}; + AudioCommon::InitSoundStream(); + Common::ScopeGuard audio_guard{AudioCommon::ShutdownSoundStream}; // The hardware is initialized. s_hardware_initialized = true; @@ -617,40 +645,15 @@ static void EmuThread() if (core_parameter.bCPUThread) g_video_backend->Video_Cleanup(); - // We must set up this flag before executing HW::Shutdown() - s_hardware_initialized = false; - INFO_LOG(CONSOLE, "%s", StopMessage(false, "Shutting down HW").c_str()); - HW::Shutdown(); - INFO_LOG(CONSOLE, "%s", StopMessage(false, "HW shutdown").c_str()); - - if (init_controllers) - { - Wiimote::Shutdown(); - Keyboard::Shutdown(); - Pad::Shutdown(); - g_controller_interface.Shutdown(); - init_controllers = false; - } - - g_video_backend->Shutdown(); - AudioCommon::ShutdownSoundStream(); - - INFO_LOG(CONSOLE, "%s", StopMessage(true, "Main Emu thread stopped").c_str()); - // Clear on screen messages that haven't expired OSD::ClearMessages(); BootManager::RestoreConfig(); - INFO_LOG(CONSOLE, "Stop [Video Thread]\t\t---- Shutdown complete ----"); - Movie::Shutdown(); PatchEngine::Shutdown(); HLE::Clear(); - - s_is_stopping = false; - - if (s_on_stopped_callback) - s_on_stopped_callback(); + // If we shut down normally, the stop message does not need to be triggered. + stop_message_guard.Dismiss(); } // Set or get the running state