diff options
author | 2021-11-12 18:38:18 +1100 | |
---|---|---|
committer | 2021-11-12 18:38:18 +1100 | |
commit | 5c8e06be77c7d7ee72b8eaa3d2dc2bfee427ea1c (patch) | |
tree | 3dd17d2a193bdddc5c682a9e75d4c1b0153f0b4b /src/osd/windows/winmain.cpp | |
parent | dc6ddf122cfbf98c1bf9d2ba705c6adfec98d847 (diff) |
-osd/windows: Show error message box on a separate thread (see MT08118).
-emu/emuopts.cpp: Default to built-in UI language rather than English.
* The external English message catalog is a placeholder anyway.
-cpu/mcs48: Corrected comments - D87xxH have UVEPROM, not EEPROM.
Diffstat (limited to 'src/osd/windows/winmain.cpp')
-rw-r--r-- | src/osd/windows/winmain.cpp | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/src/osd/windows/winmain.cpp b/src/osd/windows/winmain.cpp index 09315e5ca84..b24d2980c19 100644 --- a/src/osd/windows/winmain.cpp +++ b/src/osd/windows/winmain.cpp @@ -25,6 +25,10 @@ #include <clocale> #include <cstdarg> #include <cstdio> +#include <mutex> +#include <optional> +#include <sstream> +#include <thread> // standard windows headers #include <windows.h> @@ -55,6 +59,28 @@ class winui_output_error : public osd_output { +private: + struct ui_state + { + ~ui_state() + { + std::lock_guard guard(mutex); + if (thread) + thread->join(); + } + + std::ostringstream buffer; + std::optional<std::thread> thread; + std::mutex mutex; + bool active; + }; + + static ui_state &get_state() + { + static ui_state state; + return state; + } + public: virtual void output_callback(osd_output_channel channel, const util::format_argument_pack<std::ostream> &args) override { @@ -64,12 +90,47 @@ public: if ((video_config.windowed == 0) && !osd_common_t::s_window_list.empty()) winwindow_toggle_full_screen(); - std::ostringstream buffer; - util::stream_format(buffer, args); - win_message_box_utf8(!osd_common_t::s_window_list.empty() ? std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window() : nullptr, buffer.str().c_str(), emulator_info::get_appname(), MB_OK); + auto &state(get_state()); + std::lock_guard<std::mutex> guard(state.mutex); + util::stream_format(state.buffer, args); + if (!state.active) + { + if (state.thread) + { + state.thread->join(); + state.thread = std::nullopt; + } + auto const parent = !osd_common_t::s_window_list.empty() + ? std::static_pointer_cast<win_window_info>(osd_common_t::s_window_list.front())->platform_window() + : nullptr; + state.thread.emplace( + [parent] () + { + auto &state(get_state()); + std::string message; + while (true) + { + { + std::lock_guard<std::mutex> guard(state.mutex); + message = std::move(state.buffer).str(); + if (message.empty()) + { + state.active = false; + return; + } + state.buffer.str(std::string()); + } + // don't hold any locks lock while calling MessageBox + win_message_box_utf8(parent, message.c_str(), emulator_info::get_appname(), MB_OK); + } + }); + state.active = true; + } } else + { chain_output(channel, args); + } } }; |