diff --git a/src/xenia/kernel/xam/xam_ui.cc b/src/xenia/kernel/xam/xam_ui.cc index e555f5323..3dbe9fe0c 100644 --- a/src/xenia/kernel/xam/xam_ui.cc +++ b/src/xenia/kernel/xam/xam_ui.cc @@ -54,19 +54,6 @@ namespace xam { // // We deliberately delay the XN_SYS_UI = false notification to give games time // to create a listener (if they're insane enough do this). -XamDialog::XamDialog(xe::ui::ImGuiDrawer* imgui_drawer) - : xe::ui::ImGuiDialog(imgui_drawer) { - kernel_state()->BroadcastNotification(kXNotificationSystemUI, true); - kernel_state()->xam_state()->xam_dialogs_shown_++; -} - -XamDialog::~XamDialog() { - kernel_state()->xam_state()->xam_dialogs_shown_--; - if (kernel_state()->xam_state()->xam_dialogs_shown_ == 0) { - kernel_state()->BroadcastNotification(kXNotificationSystemUI, false); - } -} - template X_RESULT xeXamDispatchDialog(T* dialog, std::function close_callback, @@ -84,7 +71,9 @@ X_RESULT xeXamDispatchDialog(T* dialog, kernel_state()->emulator()->display_window()->app_context(); if (app_context.CallInUIThreadSynchronous( [&dialog, &fence]() { dialog->Then(&fence); })) { + kernel_state()->xam_state()->xam_dialogs_shown_++; fence.Wait(); + kernel_state()->xam_state()->xam_dialogs_shown_--; } else { delete dialog; } @@ -124,7 +113,9 @@ X_RESULT xeXamDispatchDialogEx( xe::threading::Fence fence; if (display_window->app_context().CallInUIThreadSynchronous( [&dialog, &fence]() { dialog->Then(&fence); })) { + kernel_state()->xam_state()->xam_dialogs_shown_++; fence.Wait(); + kernel_state()->xam_state()->xam_dialogs_shown_--; } else { delete dialog; } @@ -196,14 +187,19 @@ X_RESULT xeXamDispatchHeadlessEx( template X_RESULT xeXamDispatchDialogAsync(T* dialog, std::function close_callback) { + kernel_state()->BroadcastNotification(kXNotificationSystemUI, true); + kernel_state()->xam_state()->xam_dialogs_shown_++; // Important to pass captured vars by value here since we return from this // without waiting for the dialog to close so the original local vars will be // destroyed. dialog->set_close_callback([dialog, close_callback]() { close_callback(dialog); + kernel_state()->xam_state()->xam_dialogs_shown_--; + auto run = []() -> void { xe::threading::Sleep(std::chrono::milliseconds(100)); + kernel_state()->BroadcastNotification(kXNotificationSystemUI, false); }; std::thread thread(run); @@ -214,12 +210,18 @@ X_RESULT xeXamDispatchDialogAsync(T* dialog, } X_RESULT xeXamDispatchHeadlessAsync(std::function run_callback) { + kernel_state()->BroadcastNotification(kXNotificationSystemUI, true); + kernel_state()->xam_state()->xam_dialogs_shown_++; + auto display_window = kernel_state()->emulator()->display_window(); display_window->app_context().CallInUIThread([run_callback]() { run_callback(); + kernel_state()->xam_state()->xam_dialogs_shown_--; + auto run = []() -> void { xe::threading::Sleep(std::chrono::milliseconds(100)); + kernel_state()->BroadcastNotification(kXNotificationSystemUI, false); }; std::thread thread(run); diff --git a/src/xenia/kernel/xam/xam_ui.h b/src/xenia/kernel/xam/xam_ui.h index 518d67ce1..4716826e3 100644 --- a/src/xenia/kernel/xam/xam_ui.h +++ b/src/xenia/kernel/xam/xam_ui.h @@ -25,9 +25,11 @@ class XamDialog : public xe::ui::ImGuiDialog { } protected: - XamDialog(xe::ui::ImGuiDrawer* imgui_drawer); + XamDialog(xe::ui::ImGuiDrawer* imgui_drawer) + : xe::ui::ImGuiDialog(imgui_drawer) {} + + virtual ~XamDialog() {}; - ~XamDialog(); void OnClose() override { if (close_callback_) { close_callback_();