Merge pull request #7093 from Morph1984/exit
core: Properly shutdown and exit the running application when ISelfController::Exit is called
This commit is contained in:
		| @@ -421,6 +421,7 @@ struct System::Impl { | ||||
|     bool is_async_gpu{}; | ||||
|  | ||||
|     ExecuteProgramCallback execute_program_callback; | ||||
|     ExitCallback exit_callback; | ||||
|  | ||||
|     std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{}; | ||||
|     std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{}; | ||||
| @@ -798,6 +799,18 @@ void System::ExecuteProgram(std::size_t program_index) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void System::RegisterExitCallback(ExitCallback&& callback) { | ||||
|     impl->exit_callback = std::move(callback); | ||||
| } | ||||
|  | ||||
| void System::Exit() { | ||||
|     if (impl->exit_callback) { | ||||
|         impl->exit_callback(); | ||||
|     } else { | ||||
|         LOG_CRITICAL(Core, "exit_callback must be initialized by the frontend"); | ||||
|     } | ||||
| } | ||||
|  | ||||
| void System::ApplySettings() { | ||||
|     if (IsPoweredOn()) { | ||||
|         Renderer().RefreshBaseSettings(); | ||||
|   | ||||
| @@ -387,6 +387,18 @@ public: | ||||
|      */ | ||||
|     void ExecuteProgram(std::size_t program_index); | ||||
|  | ||||
|     /// Type used for the frontend to designate a callback for System to exit the application. | ||||
|     using ExitCallback = std::function<void()>; | ||||
|  | ||||
|     /** | ||||
|      * Registers a callback from the frontend for System to exit the application. | ||||
|      * @param callback Callback from the frontend to exit the application. | ||||
|      */ | ||||
|     void RegisterExitCallback(ExitCallback&& callback); | ||||
|  | ||||
|     /// Instructs the frontend to exit the application. | ||||
|     void Exit(); | ||||
|  | ||||
|     /// Applies any changes to settings to this core instance. | ||||
|     void ApplySettings(); | ||||
|  | ||||
|   | ||||
| @@ -332,10 +332,10 @@ ISelfController::~ISelfController() = default; | ||||
| void ISelfController::Exit(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_AM, "called"); | ||||
|  | ||||
|     system.Shutdown(); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2}; | ||||
|     rb.Push(ResultSuccess); | ||||
|  | ||||
|     system.Exit(); | ||||
| } | ||||
|  | ||||
| void ISelfController::LockExit(Kernel::HLERequestContext& ctx) { | ||||
|   | ||||
| @@ -302,12 +302,17 @@ GRenderWindow::GRenderWindow(GMainWindow* parent, EmuThread* emu_thread_, | ||||
|     connect(this, &GRenderWindow::FirstFrameDisplayed, parent, &GMainWindow::OnLoadComplete); | ||||
|     connect(this, &GRenderWindow::ExecuteProgramSignal, parent, &GMainWindow::OnExecuteProgram, | ||||
|             Qt::QueuedConnection); | ||||
|     connect(this, &GRenderWindow::ExitSignal, parent, &GMainWindow::OnExit, Qt::QueuedConnection); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::ExecuteProgram(std::size_t program_index) { | ||||
|     emit ExecuteProgramSignal(program_index); | ||||
| } | ||||
|  | ||||
| void GRenderWindow::Exit() { | ||||
|     emit ExitSignal(); | ||||
| } | ||||
|  | ||||
| GRenderWindow::~GRenderWindow() { | ||||
|     input_subsystem->Shutdown(); | ||||
| } | ||||
|   | ||||
| @@ -181,6 +181,9 @@ public: | ||||
|      */ | ||||
|     void ExecuteProgram(std::size_t program_index); | ||||
|  | ||||
|     /// Instructs the window to exit the application. | ||||
|     void Exit(); | ||||
|  | ||||
| public slots: | ||||
|     void OnEmulationStarting(EmuThread* emu_thread); | ||||
|     void OnEmulationStopping(); | ||||
| @@ -191,6 +194,7 @@ signals: | ||||
|     void Closed(); | ||||
|     void FirstFrameDisplayed(); | ||||
|     void ExecuteProgramSignal(std::size_t program_index); | ||||
|     void ExitSignal(); | ||||
|     void MouseActivity(); | ||||
|  | ||||
| private: | ||||
|   | ||||
| @@ -1384,6 +1384,9 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | ||||
|     system.RegisterExecuteProgramCallback( | ||||
|         [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); | ||||
|  | ||||
|     // Register an Exit callback such that Core can exit the currently running application. | ||||
|     system.RegisterExitCallback([this]() { render_window->Exit(); }); | ||||
|  | ||||
|     connect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); | ||||
|     connect(render_window, &GRenderWindow::MouseActivity, this, &GMainWindow::OnMouseActivity); | ||||
|     // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views | ||||
| @@ -2469,6 +2472,10 @@ void GMainWindow::OnExecuteProgram(std::size_t program_index) { | ||||
|     BootGame(last_filename_booted, 0, program_index); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnExit() { | ||||
|     OnStopGame(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) { | ||||
|     OverlayDialog dialog(render_window, Core::System::GetInstance(), error_code, error_text, | ||||
|                          QString{}, tr("OK"), Qt::AlignLeft | Qt::AlignVCenter); | ||||
|   | ||||
| @@ -153,6 +153,7 @@ signals: | ||||
| public slots: | ||||
|     void OnLoadComplete(); | ||||
|     void OnExecuteProgram(std::size_t program_index); | ||||
|     void OnExit(); | ||||
|     void ControllerSelectorReconfigureControllers( | ||||
|         const Core::Frontend::ControllerParameters& parameters); | ||||
|     void SoftwareKeyboardInitialize( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user