mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-11 05:26:24 +02:00
Make a little system to replace the InputBox message queue with something more generic
This commit is contained in:
1 parent
94debfbf36
commit
3852d4f698
6 files changed
+143
No files matched your search
@@ -550,6 +550,7 @@
|
||||
<ClInclude Include="Swap.h" />
|
||||
<ClInclude Include="SysError.h" />
|
||||
<ClInclude Include="System\Display.h" />
|
||||
<ClInclude Include="System\Message.h" />
|
||||
<ClInclude Include="System\NativeApp.h" />
|
||||
<ClInclude Include="System\System.h" />
|
||||
<ClInclude Include="Thread\Barrier.h" />
|
||||
@@ -1005,6 +1006,7 @@
|
||||
<ClCompile Include="OSVersion.cpp" />
|
||||
<ClCompile Include="StringUtils.cpp" />
|
||||
<ClCompile Include="System\Display.cpp" />
|
||||
<ClCompile Include="System\Message.cpp" />
|
||||
<ClCompile Include="Thread\ParallelLoop.cpp" />
|
||||
<ClCompile Include="Thread\ThreadManager.cpp" />
|
||||
<ClCompile Include="Thread\ThreadUtil.cpp" />
|
||||
|
||||
@@ -494,6 +494,9 @@
|
||||
<ClInclude Include="..\ext\basis_universal\basisu_transcoder_uastc.h">
|
||||
<Filter>ext\basis_universal</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="System\Message.h">
|
||||
<Filter>System</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ABI.cpp" />
|
||||
@@ -920,6 +923,9 @@
|
||||
<ClCompile Include="..\ext\basis_universal\basisu_transcoder.cpp">
|
||||
<Filter>ext\basis_universal</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="System\Message.cpp">
|
||||
<Filter>System</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Crypto">
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "Common/System/Message.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/Log.h"
|
||||
|
||||
RequestManager g_RequestManager;
|
||||
|
||||
const char *RequestTypeAsString(SystemRequestType type) {
|
||||
switch (type) {
|
||||
case SystemRequestType::INPUT_TEXT_MODAL: return "INPUT_TEXT_MODAL";
|
||||
default: return "N/A";
|
||||
}
|
||||
}
|
||||
|
||||
bool RequestManager::MakeSystemRequest(SystemRequestType type, RequestCallback callback, const char *param1, const char *param2) {
|
||||
int requestId = idCounter_++;
|
||||
if (!System_MakeRequest(type, requestId, param1, param2)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
// We don't expect a response, this is a one-directional request. We're thus done.
|
||||
return true;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(callbackMutex_);
|
||||
callbackMap_[requestId] = callback;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RequestManager::PostSystemResponse(int requestId, const char *responseString, int responseValue) {
|
||||
std::lock_guard<std::mutex> guard(callbackMutex_);
|
||||
auto iter = callbackMap_.find(requestId);
|
||||
if (iter == callbackMap_.end()) {
|
||||
// Unexpected!
|
||||
ERROR_LOG(SYSTEM, "PostSystemResponse: Unexpected request ID %d for %s (responseString=%s)", requestId, responseString);
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> responseGuard(responseMutex_);
|
||||
PendingResponse response;
|
||||
response.callback = iter->second;
|
||||
response.responseString = responseString;
|
||||
response.responseValue = responseValue;
|
||||
pendingResponses_.push_back(response);
|
||||
}
|
||||
|
||||
void RequestManager::ProcessRequests() {
|
||||
std::lock_guard<std::mutex> guard(responseMutex_);
|
||||
for (auto &iter : pendingResponses_) {
|
||||
if (iter.callback) {
|
||||
iter.callback(iter.responseString.c_str(), iter.responseValue);
|
||||
}
|
||||
}
|
||||
pendingResponses_.clear();
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <functional>
|
||||
|
||||
#include "Common/System/System.h"
|
||||
|
||||
typedef std::function<void(const char *responseString, int responseValue)> RequestCallback;
|
||||
|
||||
// Platforms often have to process requests asynchronously, on wildly different threads.
|
||||
// (Especially Android...)
|
||||
// This acts as bridge and buffer.
|
||||
class RequestManager {
|
||||
public:
|
||||
// These requests are to be handled by platform implementations.
|
||||
// The callback you pass in will be called on the main thread later.
|
||||
bool MakeSystemRequest(SystemRequestType type, RequestCallback callback, const char *param1, const char *param2);
|
||||
|
||||
// Called by the platform implementation, when it's finished with a request.
|
||||
void PostSystemResponse(int requestId, const char *responseString, int responseValue);
|
||||
|
||||
// This must be called every frame from the beginning of NativeUpdate().
|
||||
// This will call the callback of any finished requests.
|
||||
void ProcessRequests();
|
||||
|
||||
private:
|
||||
struct PendingRequest {
|
||||
SystemRequestType type;
|
||||
RequestCallback callback;
|
||||
};
|
||||
|
||||
std::map<int, RequestCallback> callbackMap_;
|
||||
std::mutex callbackMutex_;
|
||||
|
||||
struct PendingResponse {
|
||||
std::string responseString;
|
||||
int responseValue;
|
||||
RequestCallback callback;
|
||||
};
|
||||
|
||||
int idCounter_ = 0;
|
||||
std::vector<PendingResponse> pendingResponses_;
|
||||
std::mutex responseMutex_;
|
||||
};
|
||||
|
||||
const char *RequestTypeAsString(SystemRequestType type);
|
||||
|
||||
extern RequestManager g_RequestManager;
|
||||
@@ -146,6 +146,16 @@ enum class SystemNotification {
|
||||
SWITCH_UMD_UPDATED,
|
||||
};
|
||||
|
||||
enum class SystemRequestType {
|
||||
INPUT_TEXT_MODAL,
|
||||
};
|
||||
|
||||
// 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
|
||||
// or ignore that cleanly.
|
||||
bool System_MakeRequest(SystemRequestType type, int requestId, const char *param1, const char *param2);
|
||||
|
||||
std::string System_GetProperty(SystemProperty prop);
|
||||
std::vector<std::string> System_GetPropertyStringVec(SystemProperty prop);
|
||||
int System_GetPropertyInt(SystemProperty prop);
|
||||
|
||||
@@ -513,6 +513,26 @@ void System_InputBoxGetString(const std::string &title, const std::string &defau
|
||||
});
|
||||
}
|
||||
|
||||
bool System_PerformRequest(SystemRequestType type, int requestId, const char *param1, const char *param2) {
|
||||
switch (type) {
|
||||
case SystemRequestType::INPUT_TEXT_MODAL:
|
||||
if (inputBoxRunning) {
|
||||
inputBoxThread.join();
|
||||
}
|
||||
|
||||
inputBoxRunning = true;
|
||||
inputBoxThread = std::thread([=] {
|
||||
std::string out;
|
||||
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(title).c_str(), defaultValue, out)) {
|
||||
NativeInputBoxReceived(cb, true, out);
|
||||
} else {
|
||||
NativeInputBoxReceived(cb, false, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void System_Toast(const char *text) {
|
||||
// Not-very-good implementation. Will normally not be used on Windows anyway.
|
||||
std::wstring str = ConvertUTF8ToWString(text);
|
||||
|
||||
Reference in new issue
Block a user