mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add mechanism to run any closure on the main thread
This commit is contained in:
parent
57e114650b
commit
d6d1b5bbdc
6 changed files with 37 additions and 19 deletions
|
@ -100,6 +100,9 @@ enum class SystemRequestType {
|
|||
RUN_CALLBACK_IN_WNDPROC,
|
||||
};
|
||||
|
||||
// Run a closure on the main thread. Used to safely implement UI that runs on another thread.
|
||||
void System_RunOnMainThread(std::function<void()> func);
|
||||
|
||||
// Implementations are supposed to process the request, and post the response to the g_RequestManager (see Message.h).
|
||||
// This is not to be used directly by applications, instead use the g_RequestManager to make the requests.
|
||||
// This can return false if it's known that the platform doesn't support the request, the app is supposed to handle
|
||||
|
|
|
@ -177,7 +177,7 @@ struct PendingMessage {
|
|||
std::string value;
|
||||
};
|
||||
|
||||
static std::mutex pendingMutex;
|
||||
static std::mutex g_pendingMutex;
|
||||
static std::vector<PendingMessage> pendingMessages;
|
||||
static Draw::DrawContext *g_draw;
|
||||
static Draw::Pipeline *colorPipeline;
|
||||
|
@ -185,6 +185,7 @@ static Draw::Pipeline *texColorPipeline;
|
|||
static UIContext *uiContext;
|
||||
static int g_restartGraphics;
|
||||
static bool g_windowHidden = false;
|
||||
std::vector<std::function<void()>> g_pendingClosures;
|
||||
|
||||
#ifdef _WIN32
|
||||
WindowsAudioBackend *winAudioBackend;
|
||||
|
@ -345,6 +346,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
|
|||
setlocale( LC_ALL, "C" );
|
||||
std::string user_data_path = savegame_dir;
|
||||
pendingMessages.clear();
|
||||
g_pendingClosures.clear();
|
||||
g_requestManager.Clear();
|
||||
|
||||
// external_dir has all kinds of meanings depending on platform.
|
||||
|
@ -1047,19 +1049,28 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
|||
g_screenManager->update();
|
||||
|
||||
// Do this after g_screenManager.update() so we can receive setting changes before rendering.
|
||||
std::vector<PendingMessage> toProcess;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(pendingMutex);
|
||||
toProcess = std::move(pendingMessages);
|
||||
pendingMessages.clear();
|
||||
}
|
||||
|
||||
for (const auto &item : toProcess) {
|
||||
if (HandleGlobalMessage(item.message, item.value)) {
|
||||
// TODO: Add a to-string thingy.
|
||||
INFO_LOG(Log::System, "Handled global message: %d / %s", (int)item.message, item.value.c_str());
|
||||
std::vector<PendingMessage> toProcess;
|
||||
std::vector<std::function<void()>> toRun;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_pendingMutex);
|
||||
toProcess = std::move(pendingMessages);
|
||||
toRun = std::move(g_pendingClosures);
|
||||
pendingMessages.clear();
|
||||
g_pendingClosures.clear();
|
||||
}
|
||||
|
||||
for (auto &item : toRun) {
|
||||
item();
|
||||
}
|
||||
|
||||
for (const auto &item : toProcess) {
|
||||
if (HandleGlobalMessage(item.message, item.value)) {
|
||||
// TODO: Add a to-string thingy.
|
||||
INFO_LOG(Log::System, "Handled global message: %d / %s", (int)item.message, item.value.c_str());
|
||||
}
|
||||
g_screenManager->sendMessage(item.message, item.value.c_str());
|
||||
}
|
||||
g_screenManager->sendMessage(item.message, item.value.c_str());
|
||||
}
|
||||
|
||||
g_requestManager.ProcessRequests();
|
||||
|
@ -1404,13 +1415,18 @@ void NativeAccelerometer(float tiltX, float tiltY, float tiltZ) {
|
|||
}
|
||||
|
||||
void System_PostUIMessage(UIMessage message, const std::string &value) {
|
||||
std::lock_guard<std::mutex> lock(pendingMutex);
|
||||
std::lock_guard<std::mutex> lock(g_pendingMutex);
|
||||
PendingMessage pendingMessage;
|
||||
pendingMessage.message = message;
|
||||
pendingMessage.value = value;
|
||||
pendingMessages.push_back(pendingMessage);
|
||||
}
|
||||
|
||||
void System_RunOnMainThread(std::function<void()> func) {
|
||||
std::lock_guard<std::mutex> lock(g_pendingMutex);
|
||||
g_pendingClosures.push_back(std::move(func));
|
||||
}
|
||||
|
||||
void NativeResized() {
|
||||
// NativeResized can come from any thread so we just set a flag, then process it later.
|
||||
VERBOSE_LOG(Log::G3D, "NativeResized - setting flag");
|
||||
|
|
|
@ -497,9 +497,7 @@ namespace MainWindow {
|
|||
break;
|
||||
|
||||
case ID_EMULATION_PAUSE:
|
||||
if (!NetworkWarnUserIfOnlineAndCantSpeed()) {
|
||||
System_PostUIMessage(UIMessage::REQUEST_GAME_PAUSE);
|
||||
}
|
||||
System_PostUIMessage(UIMessage::REQUEST_GAME_PAUSE);
|
||||
break;
|
||||
|
||||
case ID_EMULATION_STOP:
|
||||
|
|
|
@ -93,6 +93,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
|||
}
|
||||
void System_Notify(SystemNotification notification) {}
|
||||
void System_PostUIMessage(UIMessage message, const std::string ¶m) {}
|
||||
void System_RunOnMainThread(std::function<void()>) {}
|
||||
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string ¶m1, const std::string ¶m2, int64_t param3, int64_t param4) {
|
||||
switch (type) {
|
||||
case SystemRequestType::SEND_DEBUG_OUTPUT:
|
||||
|
|
|
@ -1913,6 +1913,7 @@ void System_Notify(SystemNotification notification) {
|
|||
}
|
||||
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string ¶m1, const std::string ¶m2, int64_t param3, int64_t param4) { return false; }
|
||||
void System_PostUIMessage(UIMessage message, const std::string ¶m) {}
|
||||
void System_RunOnMainThread(std::function<void()>) {}
|
||||
void NativeFrame(GraphicsContext *graphicsContext) {}
|
||||
void NativeResized() {}
|
||||
|
||||
|
|
|
@ -112,6 +112,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
|
|||
}
|
||||
void System_Notify(SystemNotification notification) {}
|
||||
void System_PostUIMessage(UIMessage message, const std::string ¶m) {}
|
||||
void System_RunOnMainThread(std::function<void()>) {}
|
||||
void System_AudioGetDebugStats(char *buf, size_t bufSize) { if (buf) buf[0] = '\0'; }
|
||||
void System_AudioClear() {}
|
||||
void System_AudioPushSamples(const s32 *audio, int numSamples, float volume) {}
|
||||
|
@ -119,9 +120,7 @@ void System_AudioPushSamples(const s32 *audio, int numSamples, float volume) {}
|
|||
// TODO: To avoid having to define these here, these should probably be turned into system "requests".
|
||||
// To clear the secret entirely, just save an empty string.
|
||||
bool NativeSaveSecret(std::string_view nameOfSecret, std::string_view data) { return false; }
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) {
|
||||
return "";
|
||||
}
|
||||
std::string NativeLoadSecret(std::string_view nameOfSecret) { return ""; }
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
JNIEnv *getEnv() {
|
||||
|
|
Loading…
Add table
Reference in a new issue