Host: Expose RunOnUIThread() to core
I hate this, but sadly needed for RAIntegration...
This commit is contained in:
parent
f0d4816de7
commit
c1e01af511
|
@ -78,6 +78,9 @@ bool ChangeLanguage(const char* new_language);
|
|||
/// Safely executes a function on the VM thread.
|
||||
void RunOnCPUThread(std::function<void()> function, bool block = false);
|
||||
|
||||
/// Safely executes a function on the main/UI thread.
|
||||
void RunOnUIThread(std::function<void()> function, bool block = false);
|
||||
|
||||
/// Called when the core is creating a render device.
|
||||
/// This could also be fullscreen transition.
|
||||
std::optional<WindowInfo> AcquireRenderWindow(RenderAPI render_api, bool fullscreen, bool exclusive_fullscreen,
|
||||
|
|
|
@ -77,11 +77,9 @@ static bool SetDataDirectory();
|
|||
static bool SetCriticalFolders();
|
||||
static void SetDefaultSettings(SettingsInterface& si, bool system, bool controller);
|
||||
static std::string GetResourcePath(std::string_view name, bool allow_override);
|
||||
static void ProcessCPUThreadEvents(bool block);
|
||||
static bool PerformEarlyHardwareChecks();
|
||||
static bool EarlyProcessStartup();
|
||||
static void WarnAboutInterface();
|
||||
static void RunOnUIThread(std::function<void()> func);
|
||||
static void StartCPUThread();
|
||||
static void StopCPUThread();
|
||||
static void ProcessCPUThreadEvents(bool block);
|
||||
|
@ -580,7 +578,7 @@ std::optional<WindowInfo> Host::AcquireRenderWindow(RenderAPI render_api, bool f
|
|||
|
||||
std::optional<WindowInfo> wi;
|
||||
|
||||
MiniHost::RunOnUIThread([render_api, fullscreen, error, &wi]() {
|
||||
Host::RunOnUIThread([render_api, fullscreen, error, &wi]() {
|
||||
const std::string window_title = GetWindowTitle(System::GetGameTitle());
|
||||
const SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, window_title.c_str());
|
||||
|
@ -656,7 +654,7 @@ void Host::ReleaseRenderWindow()
|
|||
if (!s_state.sdl_window)
|
||||
return;
|
||||
|
||||
MiniHost::RunOnUIThread([]() {
|
||||
Host::RunOnUIThread([]() {
|
||||
if (!s_state.fullscreen.load(std::memory_order_acquire))
|
||||
{
|
||||
int window_x = SDL_WINDOWPOS_UNDEFINED, window_y = SDL_WINDOWPOS_UNDEFINED;
|
||||
|
@ -909,17 +907,6 @@ void MiniHost::ProcessSDLEvent(const SDL_Event* ev)
|
|||
}
|
||||
}
|
||||
|
||||
void MiniHost::RunOnUIThread(std::function<void()> func)
|
||||
{
|
||||
std::function<void()>* pfunc = new std::function<void()>(std::move(func));
|
||||
|
||||
SDL_Event ev;
|
||||
ev.user = {};
|
||||
ev.type = s_state.func_event_id;
|
||||
ev.user.data1 = pfunc;
|
||||
SDL_PushEvent(&ev);
|
||||
}
|
||||
|
||||
void MiniHost::ProcessCPUThreadPlatformMessages()
|
||||
{
|
||||
// This is lame. On Win32, we need to pump messages, even though *we* don't have any windows
|
||||
|
@ -1038,7 +1025,7 @@ void MiniHost::CPUThreadEntryPoint()
|
|||
System::CPUThreadShutdown();
|
||||
|
||||
// Tell the UI thread to shut down.
|
||||
RunOnUIThread([]() { s_state.ui_thread_running = false; });
|
||||
Host::RunOnUIThread([]() { s_state.ui_thread_running = false; });
|
||||
}
|
||||
|
||||
void MiniHost::CPUThreadMainLoop()
|
||||
|
@ -1211,6 +1198,19 @@ void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false
|
|||
s_state.cpu_thread_event_done.wait(lock, []() { return s_state.blocking_cpu_events_pending == 0; });
|
||||
}
|
||||
|
||||
void Host::RunOnUIThread(std::function<void()> function, bool block /* = false */)
|
||||
{
|
||||
using namespace MiniHost;
|
||||
|
||||
std::function<void()>* pfunc = new std::function<void()>(std::move(function));
|
||||
|
||||
SDL_Event ev;
|
||||
ev.user = {};
|
||||
ev.type = s_state.func_event_id;
|
||||
ev.user.data1 = pfunc;
|
||||
SDL_PushEvent(&ev);
|
||||
}
|
||||
|
||||
void Host::RefreshGameListAsync(bool invalidate_cache)
|
||||
{
|
||||
using namespace MiniHost;
|
||||
|
|
|
@ -661,7 +661,7 @@ void DebuggerWindow::toggleBreakpoint(VirtualMemoryAddress address)
|
|||
return;
|
||||
}
|
||||
|
||||
QtHost::RunOnUIThread([this, address, new_bp_state, bps = CPU::CopyBreakpointList()]() {
|
||||
Host::RunOnUIThread([this, address, new_bp_state, bps = CPU::CopyBreakpointList()]() {
|
||||
m_code_model->setBreakpointState(address, new_bp_state);
|
||||
refreshBreakpointList(bps);
|
||||
});
|
||||
|
@ -715,7 +715,7 @@ bool DebuggerWindow::scrollToMemoryAddress(VirtualMemoryAddress address)
|
|||
void DebuggerWindow::refreshBreakpointList()
|
||||
{
|
||||
Host::RunOnCPUThread(
|
||||
[this]() { QtHost::RunOnUIThread([this, bps = CPU::CopyBreakpointList()]() { refreshBreakpointList(bps); }); });
|
||||
[this]() { Host::RunOnUIThread([this, bps = CPU::CopyBreakpointList()]() { refreshBreakpointList(bps); }); });
|
||||
}
|
||||
|
||||
void DebuggerWindow::refreshBreakpointList(const CPU::BreakpointList& bps)
|
||||
|
@ -743,7 +743,7 @@ void DebuggerWindow::addBreakpoint(CPU::BreakpointType type, u32 address)
|
|||
{
|
||||
Host::RunOnCPUThread([this, address, type]() {
|
||||
const bool result = CPU::AddBreakpoint(type, address);
|
||||
QtHost::RunOnUIThread([this, address, type, result, bps = CPU::CopyBreakpointList()]() {
|
||||
Host::RunOnUIThread([this, address, type, result, bps = CPU::CopyBreakpointList()]() {
|
||||
if (!result)
|
||||
{
|
||||
QMessageBox::critical(this, windowTitle(),
|
||||
|
@ -763,7 +763,7 @@ void DebuggerWindow::removeBreakpoint(CPU::BreakpointType type, u32 address)
|
|||
{
|
||||
Host::RunOnCPUThread([this, address, type]() {
|
||||
const bool result = CPU::RemoveBreakpoint(type, address);
|
||||
QtHost::RunOnUIThread([this, address, type, result, bps = CPU::CopyBreakpointList()]() {
|
||||
Host::RunOnUIThread([this, address, type, result, bps = CPU::CopyBreakpointList()]() {
|
||||
if (!result)
|
||||
{
|
||||
QMessageBox::critical(this, windowTitle(), tr("Failed to remove breakpoint. This breakpoint may not exist."));
|
||||
|
|
|
@ -1037,7 +1037,7 @@ void MainWindow::populateCheatsMenu(QMenu* menu)
|
|||
if (Cheats::AreCheatsEnabled() && names.empty())
|
||||
return;
|
||||
|
||||
QtHost::RunOnUIThread([menu, names = std::move(names)]() {
|
||||
Host::RunOnUIThread([menu, names = std::move(names)]() {
|
||||
if (names.empty())
|
||||
{
|
||||
QAction* action = menu->addAction(tr("Cheats are not enabled."));
|
||||
|
@ -2368,9 +2368,9 @@ void MainWindow::openGamePropertiesForCurrentGame(const char* category /* = null
|
|||
if (path.empty() || serial.empty())
|
||||
return;
|
||||
|
||||
QtHost::RunOnUIThread([title = std::string(System::GetGameTitle()), path = std::string(path),
|
||||
serial = std::string(serial), hash = System::GetGameHash(), region = System::GetDiscRegion(),
|
||||
category]() {
|
||||
Host::RunOnUIThread([title = std::string(System::GetGameTitle()), path = std::string(path),
|
||||
serial = std::string(serial), hash = System::GetGameHash(), region = System::GetDiscRegion(),
|
||||
category]() {
|
||||
SettingsWindow::openGamePropertiesDialog(path, title, std::move(serial), hash, region, category);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1149,7 +1149,7 @@ void EmuThread::confirmActionIfMemoryCardBusy(const QString& action, bool cancel
|
|||
return;
|
||||
}
|
||||
|
||||
QtHost::RunOnUIThread([action, cancel_resume_on_accept, callback = std::move(callback)]() mutable {
|
||||
Host::RunOnUIThread([action, cancel_resume_on_accept, callback = std::move(callback)]() mutable {
|
||||
auto lock = g_main_window->pauseAndLockSystem();
|
||||
|
||||
const bool result =
|
||||
|
@ -1378,7 +1378,7 @@ void EmuThread::startControllerTest()
|
|||
return;
|
||||
}
|
||||
|
||||
QtHost::RunOnUIThread([path = std::move(path)]() mutable {
|
||||
Host::RunOnUIThread([path = std::move(path)]() mutable {
|
||||
{
|
||||
auto lock = g_main_window->pauseAndLockSystem();
|
||||
if (QMessageBox::question(
|
||||
|
@ -1397,7 +1397,7 @@ void EmuThread::startControllerTest()
|
|||
});
|
||||
}
|
||||
|
||||
void EmuThread::runOnEmuThread(std::function<void()> callback)
|
||||
void EmuThread::runOnEmuThread(const std::function<void()>& callback)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
|
@ -1411,11 +1411,11 @@ void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false
|
|||
Q_ARG(std::function<void()>, std::move(function)));
|
||||
}
|
||||
|
||||
void QtHost::RunOnUIThread(const std::function<void()>& func, bool block /*= false*/)
|
||||
void Host::RunOnUIThread(std::function<void()> function, bool block /* = false*/)
|
||||
{
|
||||
// main window always exists, so it's fine to attach it to that.
|
||||
QMetaObject::invokeMethod(g_main_window, "runOnUIThread", block ? Qt::BlockingQueuedConnection : Qt::QueuedConnection,
|
||||
Q_ARG(const std::function<void()>&, func));
|
||||
Q_ARG(std::function<void()>, std::move(function)));
|
||||
}
|
||||
|
||||
QtAsyncTask::QtAsyncTask(WorkCallback callback)
|
||||
|
@ -1432,7 +1432,7 @@ void QtAsyncTask::create(QObject* owner, WorkCallback callback)
|
|||
connect(task, &QtAsyncTask::completed, owner, [task]() { std::get<CompletionCallback>(task->m_callback)(); });
|
||||
System::QueueAsyncTask([task]() {
|
||||
task->m_callback = std::get<WorkCallback>(task->m_callback)();
|
||||
QtHost::RunOnUIThread([task]() {
|
||||
Host::RunOnUIThread([task]() {
|
||||
emit task->completed(task);
|
||||
delete task;
|
||||
});
|
||||
|
@ -1710,10 +1710,9 @@ void Host::OpenHostFileSelectorAsync(std::string_view title, bool select_directo
|
|||
}
|
||||
}
|
||||
|
||||
QtHost::RunOnUIThread([title = QtUtils::StringViewToQString(title), select_directory, callback = std::move(callback),
|
||||
filters_str = std::move(filters_str),
|
||||
initial_directory = QtUtils::StringViewToQString(initial_directory),
|
||||
from_cpu_thread]() mutable {
|
||||
Host::RunOnUIThread([title = QtUtils::StringViewToQString(title), select_directory, callback = std::move(callback),
|
||||
filters_str = std::move(filters_str),
|
||||
initial_directory = QtUtils::StringViewToQString(initial_directory), from_cpu_thread]() mutable {
|
||||
auto lock = g_main_window->pauseAndLockSystem();
|
||||
|
||||
QString path;
|
||||
|
@ -2103,9 +2102,9 @@ void Host::ConfirmMessageAsync(std::string_view title, std::string_view message,
|
|||
else
|
||||
{
|
||||
// Otherwise, use the desktop UI.
|
||||
QtHost::RunOnUIThread([title = QtUtils::StringViewToQString(title), message = QtUtils::StringViewToQString(message),
|
||||
callback = std::move(callback), yes_text = QtUtils::StringViewToQString(yes_text),
|
||||
no_text = QtUtils::StringViewToQString(no_text), needs_pause]() mutable {
|
||||
Host::RunOnUIThread([title = QtUtils::StringViewToQString(title), message = QtUtils::StringViewToQString(message),
|
||||
callback = std::move(callback), yes_text = QtUtils::StringViewToQString(yes_text),
|
||||
no_text = QtUtils::StringViewToQString(no_text), needs_pause]() mutable {
|
||||
auto lock = g_main_window->pauseAndLockSystem();
|
||||
|
||||
bool result;
|
||||
|
@ -2136,14 +2135,14 @@ void Host::ConfirmMessageAsync(std::string_view title, std::string_view message,
|
|||
|
||||
void Host::OpenURL(std::string_view url)
|
||||
{
|
||||
QtHost::RunOnUIThread([url = QtUtils::StringViewToQString(url)]() { QtUtils::OpenURL(g_main_window, QUrl(url)); });
|
||||
Host::RunOnUIThread([url = QtUtils::StringViewToQString(url)]() { QtUtils::OpenURL(g_main_window, QUrl(url)); });
|
||||
}
|
||||
|
||||
std::string Host::GetClipboardText()
|
||||
{
|
||||
// Hope this doesn't deadlock...
|
||||
std::string ret;
|
||||
QtHost::RunOnUIThread(
|
||||
Host::RunOnUIThread(
|
||||
[&ret]() {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
if (clipboard)
|
||||
|
@ -2155,7 +2154,7 @@ std::string Host::GetClipboardText()
|
|||
|
||||
bool Host::CopyTextToClipboard(std::string_view text)
|
||||
{
|
||||
QtHost::RunOnUIThread([text = QtUtils::StringViewToQString(text)]() {
|
||||
Host::RunOnUIThread([text = QtUtils::StringViewToQString(text)]() {
|
||||
QClipboard* clipboard = QGuiApplication::clipboard();
|
||||
if (clipboard)
|
||||
clipboard->setText(text);
|
||||
|
@ -2543,7 +2542,7 @@ void QtHost::QueueSettingsSave()
|
|||
{
|
||||
if (!QThread::isMainThread())
|
||||
{
|
||||
QtHost::RunOnUIThread(QueueSettingsSave);
|
||||
Host::RunOnUIThread(QueueSettingsSave);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ private Q_SLOTS:
|
|||
void onDisplayWindowKeyEvent(int key, bool pressed);
|
||||
void onDisplayWindowTextEntered(const QString& text);
|
||||
void doBackgroundControllerPoll();
|
||||
void runOnEmuThread(std::function<void()> callback);
|
||||
void runOnEmuThread(const std::function<void()>& callback);
|
||||
void processAuxiliaryRenderWindowInputEvent(void* userdata, quint32 event, quint32 param1, quint32 param2,
|
||||
quint32 param3);
|
||||
|
||||
|
@ -358,9 +358,6 @@ bool IsRunningOnWayland();
|
|||
/// Returns true if rendering to the main window should be allowed.
|
||||
bool CanRenderToMainWindow();
|
||||
|
||||
/// Executes a function on the UI thread.
|
||||
void RunOnUIThread(const std::function<void()>& func, bool block = false);
|
||||
|
||||
/// Default language for the platform.
|
||||
const char* GetDefaultLanguage();
|
||||
|
||||
|
|
|
@ -225,7 +225,7 @@ std::span<const std::pair<const char*, const char*>> Host::GetAvailableLanguageL
|
|||
|
||||
bool Host::ChangeLanguage(const char* new_language)
|
||||
{
|
||||
QtHost::RunOnUIThread([new_language = std::string(new_language)]() {
|
||||
Host::RunOnUIThread([new_language = std::string(new_language)]() {
|
||||
Host::SetBaseStringSettingValue("Main", "Language", new_language.c_str());
|
||||
Host::CommitBaseSettingChanges();
|
||||
QtHost::UpdateApplicationLanguage(g_main_window);
|
||||
|
@ -283,8 +283,7 @@ void QtHost::UpdateGlyphRangesAndClearCache(QWidget* dialog_parent, std::string_
|
|||
// If we don't have any specific glyph range, assume Central European, except if English, then keep the size down.
|
||||
if ((!gi || !gi->used_glyphs) && language != "en")
|
||||
{
|
||||
glyph_ranges.insert(glyph_ranges.end(), std::begin(s_central_european_ranges),
|
||||
std::end(s_central_european_ranges));
|
||||
glyph_ranges.insert(glyph_ranges.end(), std::begin(s_central_european_ranges), std::end(s_central_european_ranges));
|
||||
}
|
||||
|
||||
// List terminator.
|
||||
|
|
|
@ -381,6 +381,11 @@ void RegTestHost::ProcessCPUThreadEvents()
|
|||
}
|
||||
}
|
||||
|
||||
void Host::RunOnUIThread(std::function<void()> function, bool block /* = false */)
|
||||
{
|
||||
RunOnCPUThread(std::move(function), block);
|
||||
}
|
||||
|
||||
void Host::RequestResizeHostDisplay(s32 width, s32 height)
|
||||
{
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue