Merge pull request #17158 from hrydgard/even-more-system-cleanup

More system cleanup: Replace inputbox queue with something more generic
This commit is contained in:
Henrik Rydgård authored and GitHub committed 2023-03-22 14:52:58 +01:00
commit 96012b2470
30 files changed
+406 -233

No files matched your search

+4
View File
@@ -712,6 +712,10 @@ add_library(Common STATIC
Common/Render/Text/draw_text_uwp.h
Common/System/Display.cpp
Common/System/Display.h
Common/System/System.h
Common/System/NativeApp.h
Common/System/Request.cpp
Common/System/Request.h
Common/Thread/Channel.h
Common/Thread/ParallelLoop.cpp
Common/Thread/ParallelLoop.h
+2
View File
@@ -550,6 +550,7 @@
<ClInclude Include="Swap.h" />
<ClInclude Include="SysError.h" />
<ClInclude Include="System\Display.h" />
<ClInclude Include="System\Request.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\Request.cpp" />
<ClCompile Include="Thread\ParallelLoop.cpp" />
<ClCompile Include="Thread\ThreadManager.cpp" />
<ClCompile Include="Thread\ThreadUtil.cpp" />
+6
View File
@@ -494,6 +494,9 @@
<ClInclude Include="..\ext\basis_universal\basisu_transcoder_uastc.h">
<Filter>ext\basis_universal</Filter>
</ClInclude>
<ClInclude Include="System\Request.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\Request.cpp">
<Filter>System</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="Crypto">
-3
View File
@@ -23,9 +23,6 @@ void NativeGetAppInfo(std::string *app_dir_name, std::string *app_nice_name, boo
// Generic host->C++ messaging, used for functionality like system-native popup input boxes.
void NativeMessageReceived(const char *message, const char *value);
// This is used to communicate back and thread requested input box strings.
void NativeInputBoxReceived(std::function<void(bool, const std::string &)> cb, bool result, const std::string &value);
// Easy way for the Java side to ask the C++ side for configuration options, such as
// the rotation lock which must be controlled from Java on Android.
// It is currently not called on non-Android platforms.
+72
View File
@@ -0,0 +1,72 @@
#include "Common/System/Request.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 std::string &param1, const std::string &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::PostSystemSuccess(int requestId, const char *responseString, int responseValue) {
std::lock_guard<std::mutex> guard(callbackMutex_);
auto iter = callbackMap_.find(requestId);
if (iter == callbackMap_.end()) {
ERROR_LOG(SYSTEM, "PostSystemSuccess: Unexpected request ID %d (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::PostSystemFailure(int requestId) {
std::lock_guard<std::mutex> guard(callbackMutex_);
auto iter = callbackMap_.find(requestId);
if (iter == callbackMap_.end()) {
ERROR_LOG(SYSTEM, "PostSystemFailure: Unexpected request ID %d", requestId);
return;
}
callbackMap_.erase(iter);
}
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();
}
void RequestManager::Clear() {
std::lock_guard<std::mutex> guard(callbackMutex_);
std::lock_guard<std::mutex> responseGuard(responseMutex_);
pendingResponses_.clear();
callbackMap_.clear();
}
+60
View File
@@ -0,0 +1,60 @@
#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 std::string &param1, const std::string &param2);
// Called by the platform implementation, when it's finished with a request.
void PostSystemSuccess(int requestId, const char *responseString, int responseValue = 0);
void PostSystemFailure(int requestId);
// This must be called every frame from the beginning of NativeUpdate().
// This will call the callback of any finished requests.
void ProcessRequests();
// Unclear if we need this...
void Clear();
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;
// Wrappers for easy requests.
// NOTE: Semantics have changed - this no longer calls the callback on cancellation.
inline void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, RequestCallback callback) {
g_requestManager.MakeSystemRequest(SystemRequestType::INPUT_TEXT_MODAL, callback, title, defaultValue);
}
+13 -1
View File
@@ -50,8 +50,20 @@ enum class LaunchUrlType {
void System_Vibrate(int length_ms);
void System_ShowFileInFolder(const char *path);
void System_LaunchUrl(LaunchUrlType urlType, const char *url);
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb);
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 std::string &param1, const std::string &param2);
// TODO: To be separated into requests, see Request.h, and a way to post "UI messages".
void System_SendMessage(const char *command, const char *parameter);
PermissionStatus System_GetPermissionStatus(SystemPermission permission);
void System_AskForPermission(SystemPermission permission);
+3 -3
View File
@@ -22,7 +22,7 @@
#include "Common/Math/math_util.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/Serialize/Serializer.h"
#include "Core/Dialog/PSPOskDialog.h"
@@ -892,14 +892,14 @@ int PSPOskDialog::NativeKeyboard() {
defaultText.assign(u"VALUE");
// There's already ConvertUCS2ToUTF8 in this file. Should we use that instead of the global ones?
System_InputBoxGetString(::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), [&](bool result, const std::string &value) {
System_InputBoxGetString(::ConvertUCS2ToUTF8(titleText), ::ConvertUCS2ToUTF8(defaultText), [&](const std::string &value, int iValue) {
std::lock_guard<std::mutex> guard(nativeMutex_);
if (nativeStatus_ != PSPOskNativeStatus::WAITING) {
return;
}
nativeValue_ = value;
nativeStatus_ = result ? PSPOskNativeStatus::SUCCESS : PSPOskNativeStatus::FAILURE;
nativeStatus_ = iValue ? PSPOskNativeStatus::SUCCESS : PSPOskNativeStatus::FAILURE;
});
} else if (nativeStatus_ == PSPOskNativeStatus::SUCCESS) {
inputChars = ConvertUTF8ToUCS2(nativeValue_);
+57 -27
View File
@@ -34,7 +34,7 @@
#endif
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/GPU/OpenGL/GLFeatures.h"
#include "Common/Math/math_util.h"
#include "Common/Profiler/Profiler.h"
@@ -58,6 +58,8 @@ MainUI *emugl = nullptr;
static float refreshRate = 60.f;
static int browseFileEvent = -1;
static int browseFolderEvent = -1;
static int inputBoxEvent = -1;
QTCamera *qtcamera = nullptr;
MainWindow *g_mainWindow;
@@ -273,6 +275,57 @@ void System_Notify(SystemNotification notification) {
}
}
// TODO: Find a better version to pass parameters to HandleCustomEvent.
static std::string g_param1;
static std::string g_param2;
static int g_requestId;
bool MainUI::HandleCustomEvent(QEvent *e) {
if (e->type() == browseFileEvent) {
QString fileName = QFileDialog::getOpenFileName(nullptr, "Load ROM", g_Config.currentDirectory.c_str(), "PSP ROMs (*.iso *.cso *.pbp *.elf *.zip *.ppdmp)");
if (QFile::exists(fileName)) {
QDir newPath;
g_Config.currentDirectory = Path(newPath.filePath(fileName).toStdString());
g_Config.Save("browseFileEvent");
NativeMessageReceived("boot", fileName.toStdString().c_str());
}
} else if (e->type() == browseFolderEvent) {
auto mm = GetI18NCategory("MainMenu");
QString fileName = QFileDialog::getExistingDirectory(nullptr, mm->T("Choose folder"), g_Config.currentDirectory.c_str());
if (QDir(fileName).exists()) {
NativeMessageReceived("browse_folderSelect", fileName.toStdString().c_str());
}
} else if (e->type() == inputBoxEvent) {
QString title = QString::fromStdString(g_param1);
QString defaultValue = QString::fromStdString(g_param2);
QString text = emugl->InputBoxGetQString(title, defaultValue);
if (text.isEmpty()) {
g_requestManager.PostSystemFailure(g_requestId);
} else {
g_requestManager.PostSystemSuccess(g_requestId, text.toStdString().c_str());
}
} else {
return false;
}
return true;
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) {
switch (type) {
case SystemRequestType::INPUT_TEXT_MODAL:
{
g_requestId = requestId;
g_param1 = param1;
g_param2 = param2;
QCoreApplication::postEvent(emugl, new QEvent((QEvent::Type)inputBoxEvent));
return true;
}
default:
return false;
}
}
void System_SendMessage(const char *command, const char *parameter) {
if (!strcmp(command, "finish")) {
qApp->exit(0);
@@ -305,15 +358,6 @@ void System_Toast(const char *text) {}
void System_AskForPermission(SystemPermission permission) {}
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) {
QString text = emugl->InputBoxGetQString(QString::fromStdString(title), QString::fromStdString(defaultValue));
if (text.isEmpty()) {
NativeInputBoxReceived(cb, false, "");
} else {
NativeInputBoxReceived(cb, true, text.toStdString());
}
}
void System_Vibrate(int length_ms) {
if (length_ms == -1 || length_ms == -3)
length_ms = 50;
@@ -355,6 +399,7 @@ static int mainInternal(QApplication &a) {
browseFileEvent = QEvent::registerEventType();
browseFolderEvent = QEvent::registerEventType();
inputBoxEvent = QEvent::registerEventType();
int retval = a.exec();
delete emugl;
@@ -566,23 +611,8 @@ bool MainUI::event(QEvent *e) {
break;
default:
if (e->type() == browseFileEvent) {
QString fileName = QFileDialog::getOpenFileName(nullptr, "Load ROM", g_Config.currentDirectory.c_str(), "PSP ROMs (*.iso *.cso *.pbp *.elf *.zip *.ppdmp)");
if (QFile::exists(fileName)) {
QDir newPath;
g_Config.currentDirectory = Path(newPath.filePath(fileName).toStdString());
g_Config.Save("browseFileEvent");
NativeMessageReceived("boot", fileName.toStdString().c_str());
}
break;
} else if (e->type() == browseFolderEvent) {
auto mm = GetI18NCategory("MainMenu");
QString fileName = QFileDialog::getExistingDirectory(nullptr, mm->T("Choose folder"), g_Config.currentDirectory.c_str());
if (QDir(fileName).exists()) {
NativeMessageReceived("browse_folderSelect", fileName.toStdString().c_str());
}
} else {
// Can't switch on dynamic event types.
if (!HandleCustomEvent(e)) {
return QWidget::event(e);
}
}
+1
View File
@@ -140,6 +140,7 @@ protected:
void EmuThreadJoin();
private:
bool HandleCustomEvent(QEvent *e);
QtGLGraphicsContext *graphicsContext;
float xscale, yscale;
+6 -6
View File
@@ -7,11 +7,9 @@ Additional code by many contributors, see the Credits screen
Originally released under the GPL 2.0 (and later) in November 2012
Official website:
https://www.ppsspp.org/
Official website: https://www.ppsspp.org/
Discord:
https://discord.gg/5NJB6dD
Discord: https://discord.gg/5NJB6dD
No BIOS file required to play, PPSSPP is an "HLE" emulator. Default settings balance good compatibility and speed.
@@ -19,9 +17,11 @@ To contribute, see [the development page](https://www.ppsspp.org/development.htm
For the latest source code, see [our GitHub page](https://github.com/hrydgard/ppsspp).
For documentation of all kinds (usage, reference, development), see the [documentation on the main website](https://www.ppsspp.org/docs)
For build instructions and other development tutorials, see [the wiki](https://github.com/hrydgard/ppsspp/wiki).
If you want to download regularly updated builds for Android, Windows x86 and x64, proceed to this [page](https://buildbot.orphis.net/ppsspp/)
If you want to download regularly updated builds for Android, Windows x86 and x64, [visit Orphis' buildbot](https://buildbot.orphis.net/ppsspp/)
For game compatibility, see [community compatibility feedback](https://report.ppsspp.org/games).
@@ -412,4 +412,4 @@ Credit goes to:
[#16709]: https://github.com/hrydgard/ppsspp/issues/16709 "Correct some shader errors in reporting"
[#16708]: https://github.com/hrydgard/ppsspp/issues/16708 "Additional fixes from both our reports and Play reports"
[#16703]: https://github.com/hrydgard/ppsspp/issues/16703 "Minor fixes based on the latest Google Play report"
[#16706]: https://github.com/hrydgard/ppsspp/issues/16706 "softgpu: Fix lighting with 0 exp"
[#16706]: https://github.com/hrydgard/ppsspp/issues/16706 "softgpu: Fix lighting with 0 exp"
+2
View File
@@ -166,6 +166,8 @@ void System_Vibrate(int length_ms) {
// Ignore on PC
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) { return false; }
void System_SendMessage(const char *command, const char *parameter) {
if (!strcmp(command, "toggle_fullscreen")) {
g_ToggleFullScreenNextFrame = true;
+4 -6
View File
@@ -10,7 +10,7 @@
#include "Common/Data/Text/I18n.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "Core/HLE/proAdhoc.h"
@@ -97,7 +97,7 @@ UI::EventReturn ChatMenu::OnSubmit(UI::EventParams &e) {
sendChat(chat);
#elif PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Chat"), "", [](bool result, const std::string &value) {
System_InputBoxGetString(n->T("Chat"), "", [](const std::string &value, int) {
sendChat(value);
});
#endif
@@ -181,10 +181,8 @@ void ChatMenu::Update() {
#if defined(USING_WIN_UI)
// Could remove the fullscreen check here, it works now.
if (promptInput_ && g_Config.bBypassOSKWithKeyboard && !g_Config.UseFullScreen()) {
System_InputBoxGetString(n->T("Chat"), n->T("Chat Here"), [](bool result, const std::string &value) {
if (result) {
sendChat(value);
}
System_InputBoxGetString(n->T("Chat"), n->T("Chat Here"), [](const std::string &value, int) {
sendChat(value);
});
promptInput_ = false;
}
+17 -33
View File
@@ -30,7 +30,7 @@
#include "Common/VR/PPSSPPVR.h"
#include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/Battery/Battery.h"
#include "Common/System/NativeApp.h"
#include "Common/Data/Color/RGBAUtil.h"
@@ -1564,10 +1564,8 @@ UI::EventReturn GameSettingsScreen::OnAudioDevice(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, [](bool result, const std::string &value) {
if (result) {
g_Config.sQuickChat0 = value;
}
System_InputBoxGetString(n->T("Enter Quick Chat 1"), g_Config.sQuickChat0, [](const std::string &value, int) {
g_Config.sQuickChat0 = value;
});
#endif
return UI::EVENT_DONE;
@@ -1576,10 +1574,8 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat0(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, [](bool result, const std::string &value) {
if (result) {
g_Config.sQuickChat1 = value;
}
System_InputBoxGetString(n->T("Enter Quick Chat 2"), g_Config.sQuickChat1, [](const std::string &value, int) {
g_Config.sQuickChat1 = value;
});
#endif
return UI::EVENT_DONE;
@@ -1588,10 +1584,8 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat1(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, [](bool result, const std::string &value) {
if (result) {
g_Config.sQuickChat2 = value;
}
System_InputBoxGetString(n->T("Enter Quick Chat 3"), g_Config.sQuickChat2, [](const std::string &value, int) {
g_Config.sQuickChat2 = value;
});
#endif
return UI::EVENT_DONE;
@@ -1600,10 +1594,8 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat2(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, [](bool result, const std::string &value) {
if (result) {
g_Config.sQuickChat3 = value;
}
System_InputBoxGetString(n->T("Enter Quick Chat 4"), g_Config.sQuickChat3, [](const std::string &value, int) {
g_Config.sQuickChat3 = value;
});
#endif
return UI::EVENT_DONE;
@@ -1612,10 +1604,8 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat3(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, [](bool result, const std::string &value) {
if (result) {
g_Config.sQuickChat4 = value;
}
System_InputBoxGetString(n->T("Enter Quick Chat 5"), g_Config.sQuickChat4, [](const std::string &value, int) {
g_Config.sQuickChat4 = value;
});
#endif
return UI::EVENT_DONE;
@@ -1624,10 +1614,8 @@ UI::EventReturn GameSettingsScreen::OnChangeQuickChat4(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeNickname(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || PPSSPP_PLATFORM(ANDROID)
auto n = GetI18NCategory("Networking");
System_InputBoxGetString(n->T("Enter a new PSP nickname"), g_Config.sNickName, [](bool result, const std::string &value) {
if (result) {
g_Config.sNickName = StripSpaces(value);
}
System_InputBoxGetString(n->T("Enter a new PSP nickname"), g_Config.sNickName, [](const std::string &value, int) {
g_Config.sNickName = StripSpaces(value);
});
#endif
return UI::EVENT_DONE;
@@ -1723,10 +1711,8 @@ UI::EventReturn GameSettingsScreen::OnSysInfo(UI::EventParams &e) {
UI::EventReturn GameSettingsScreen::OnChangeSearchFilter(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__)
auto se = GetI18NCategory("Search");
System_InputBoxGetString(se->T("Search term"), searchFilter_, [](bool result, const std::string &value) {
if (result) {
NativeMessageReceived("gameSettings_search", StripSpaces(value).c_str());
}
System_InputBoxGetString(se->T("Search term"), searchFilter_, [](const std::string &value, int) {
NativeMessageReceived("gameSettings_search", StripSpaces(value).c_str());
});
#else
if (!System_GetPropertyBool(SYSPROP_HAS_KEYBOARD))
@@ -2098,10 +2084,8 @@ UI::EventReturn HostnameSelectScreen::OnDeleteAllClick(UI::EventParams &e) {
UI::EventReturn HostnameSelectScreen::OnEditClick(UI::EventParams& e) {
auto n = GetI18NCategory("Networking");
#if PPSSPP_PLATFORM(ANDROID)
System_InputBoxGetString(n->T("proAdhocServer Address:"), addrView_->GetText(), [this](bool result, const std::string& value) {
if (result) {
addrView_->SetText(value);
}
System_InputBoxGetString(n->T("proAdhocServer Address:"), addrView_->GetText(), [this](const std::string& value, int) {
addrView_->SetText(value);
});
#endif
return UI::EVENT_DONE;
+46 -47
View File
@@ -26,6 +26,7 @@
#include "Common/StringUtils.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/System/NativeApp.h"
#include "Common/System/Display.h"
#include "Common/Data/Text/I18n.h"
@@ -336,64 +337,62 @@ UI::EventReturn MemStickScreen::SetFolderManually(UI::EventParams &params) {
// The old way, from before scoped storage.
#if PPSSPP_PLATFORM(ANDROID)
auto sy = GetI18NCategory("System");
System_InputBoxGetString(sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), [&](bool result, const std::string &value) {
System_InputBoxGetString(sy->T("Memory Stick Folder"), g_Config.memStickDirectory.ToString(), [&](const std::string &value, int) {
auto sy = GetI18NCategory("System");
auto di = GetI18NCategory("Dialog");
if (result) {
std::string newPath = value;
size_t pos = newPath.find_last_not_of("/");
// Gotta have at least something but a /, and also needs to start with a /.
if (newPath.empty() || pos == newPath.npos || newPath[0] != '/') {
settingInfo_->Show(sy->T("ChangingMemstickPathInvalid", "That path couldn't be used to save Memory Stick files."), nullptr);
return;
}
if (pos != newPath.size() - 1) {
newPath = newPath.substr(0, pos + 1);
}
std::string newPath = value;
size_t pos = newPath.find_last_not_of("/");
// Gotta have at least something but a /, and also needs to start with a /.
if (newPath.empty() || pos == newPath.npos || newPath[0] != '/') {
settingInfo_->Show(sy->T("ChangingMemstickPathInvalid", "That path couldn't be used to save Memory Stick files."), nullptr);
return;
}
if (pos != newPath.size() - 1) {
newPath = newPath.substr(0, pos + 1);
}
if (newPath.empty()) {
// Reuse below message instead of adding yet another string.
System_Toast(sy->T("Path does not exist!"));
return;
}
if (newPath.empty()) {
// Reuse below message instead of adding yet another string.
System_Toast(sy->T("Path does not exist!"));
return;
}
Path pendingMemStickFolder(newPath);
Path pendingMemStickFolder(newPath);
if (!File::Exists(pendingMemStickFolder)) {
// Try to fix the path string, apparently some users got used to leaving out the /.
if (newPath[0] != '/') {
newPath = "/" + newPath;
}
if (!File::Exists(pendingMemStickFolder)) {
// Try to fix the path string, apparently some users got used to leaving out the /.
if (newPath[0] != '/') {
newPath = "/" + newPath;
}
pendingMemStickFolder = Path(newPath);
}
pendingMemStickFolder = Path(newPath);
}
if (!File::Exists(pendingMemStickFolder) && pendingMemStickFolder.Type() == PathType::NATIVE) {
// Still no path? Try to automatically fix the case.
std::string oldNewPath = newPath;
FixPathCase(Path(""), newPath, FixPathCaseBehavior::FPC_FILE_MUST_EXIST);
if (oldNewPath != newPath) {
NOTICE_LOG(IO, "Fixed path case: %s -> %s", oldNewPath.c_str(), newPath.c_str());
pendingMemStickFolder = Path(newPath);
} else {
NOTICE_LOG(IO, "Failed to fix case of path %s (result: %s)", newPath.c_str(), oldNewPath.c_str());
}
}
if (!File::Exists(pendingMemStickFolder) && pendingMemStickFolder.Type() == PathType::NATIVE) {
// Still no path? Try to automatically fix the case.
std::string oldNewPath = newPath;
FixPathCase(Path(""), newPath, FixPathCaseBehavior::FPC_FILE_MUST_EXIST);
if (oldNewPath != newPath) {
NOTICE_LOG(IO, "Fixed path case: %s -> %s", oldNewPath.c_str(), newPath.c_str());
pendingMemStickFolder = Path(newPath);
} else {
NOTICE_LOG(IO, "Failed to fix case of path %s (result: %s)", newPath.c_str(), oldNewPath.c_str());
}
}
if (pendingMemStickFolder == g_Config.memStickDirectory) {
// Same directory as before - all good. Nothing to do.
TriggerFinish(DialogResult::DR_OK);
return;
}
if (pendingMemStickFolder == g_Config.memStickDirectory) {
// Same directory as before - all good. Nothing to do.
TriggerFinish(DialogResult::DR_OK);
return;
}
if (!File::Exists(pendingMemStickFolder)) {
System_Toast(sy->T("Path does not exist!"));
return;
}
if (!File::Exists(pendingMemStickFolder)) {
System_Toast(sy->T("Path does not exist!"));
return;
}
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
}
screenManager()->push(new ConfirmMemstickMoveScreen(pendingMemStickFolder, false));
});
#endif
return UI::EVENT_DONE;
+41 -59
View File
@@ -58,8 +58,10 @@
#include "android/jni/app-android.h"
#include "Common/System/Display.h"
#include "Common/System/Request.h"
#include "Common/System/System.h"
#include "Common/System/NativeApp.h"
#include "Common/Data/Text/I18n.h"
#include "Common/Input/InputState.h"
#include "Common/Math/math_util.h"
@@ -148,7 +150,7 @@
#include <Core/HLE/Plugins.h>
ScreenManager *screenManager;
ScreenManager *g_screenManager;
std::string config_filename;
// Really need to clean this mess of globals up... but instead I add more :P
@@ -164,15 +166,8 @@ struct PendingMessage {
std::string value;
};
struct PendingInputBox {
std::function<void(bool, const std::string &)> cb;
bool result;
std::string value;
};
static std::mutex pendingMutex;
static std::vector<PendingMessage> pendingMessages;
static std::vector<PendingInputBox> pendingInputBoxes;
static Draw::DrawContext *g_draw;
static Draw::Pipeline *colorPipeline;
static Draw::Pipeline *texColorPipeline;
@@ -443,7 +438,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();
pendingInputBoxes.clear();
g_requestManager.Clear();
// external_dir has all kinds of meanings depending on platform.
// on iOS it's even the path to bundled app assets. It's a mess.
@@ -789,19 +784,19 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
}
DEBUG_LOG(SYSTEM, "ScreenManager!");
screenManager = new ScreenManager();
g_screenManager = new ScreenManager();
if (g_Config.memStickDirectory.empty()) {
INFO_LOG(SYSTEM, "No memstick directory! Asking for one to be configured.");
screenManager->switchScreen(new LogoScreen(AfterLogoScreen::MEMSTICK_SCREEN_INITIAL_SETUP));
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::MEMSTICK_SCREEN_INITIAL_SETUP));
} else if (gotoGameSettings) {
screenManager->switchScreen(new LogoScreen(AfterLogoScreen::TO_GAME_SETTINGS));
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::TO_GAME_SETTINGS));
} else if (gotoTouchScreenTest) {
screenManager->switchScreen(new MainScreen());
screenManager->push(new TouchTestScreen(Path()));
g_screenManager->switchScreen(new MainScreen());
g_screenManager->push(new TouchTestScreen(Path()));
} else if (skipLogo) {
screenManager->switchScreen(new EmuScreen(boot_filename));
g_screenManager->switchScreen(new EmuScreen(boot_filename));
} else {
screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
g_screenManager->switchScreen(new LogoScreen(AfterLogoScreen::DEFAULT));
}
// Easy testing
@@ -833,7 +828,7 @@ bool CreateGlobalPipelines();
bool NativeInitGraphics(GraphicsContext *graphicsContext) {
INFO_LOG(SYSTEM, "NativeInitGraphics");
_assert_(screenManager);
_assert_(g_screenManager);
// We set this now so any resize during init is processed later.
resized = false;
@@ -864,10 +859,10 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
if (uiContext->Text())
uiContext->Text()->SetFont("Tahoma", 20, 0);
screenManager->setUIContext(uiContext);
screenManager->setDrawContext(g_draw);
screenManager->setPostRenderCallback(&RenderOverlays, nullptr);
screenManager->deviceRestored();
g_screenManager->setUIContext(uiContext);
g_screenManager->setDrawContext(g_draw);
g_screenManager->setPostRenderCallback(&RenderOverlays, nullptr);
g_screenManager->deviceRestored();
#ifdef _WIN32
winAudioBackend = CreateAudioBackend((AudioBackendType)g_Config.iAudioBackend);
@@ -951,8 +946,8 @@ bool CreateGlobalPipelines() {
void NativeShutdownGraphics() {
INFO_LOG(SYSTEM, "NativeShutdownGraphics");
if (screenManager) {
screenManager->deviceLost();
if (g_screenManager) {
g_screenManager->deviceLost();
}
if (gpu)
@@ -1062,7 +1057,7 @@ void RenderOverlays(UIContext *dc, void *userdata) {
void NativeRender(GraphicsContext *graphicsContext) {
_dbg_assert_(graphicsContext != nullptr);
_dbg_assert_(screenManager != nullptr);
_dbg_assert_(g_screenManager != nullptr);
g_GameManager.Update();
@@ -1108,19 +1103,19 @@ void NativeRender(GraphicsContext *graphicsContext) {
ui_draw2d.PushDrawMatrix(ortho);
ui_draw2d_front.PushDrawMatrix(ortho);
screenManager->getUIContext()->SetTintSaturation(g_Config.fUITint, g_Config.fUISaturation);
g_screenManager->getUIContext()->SetTintSaturation(g_Config.fUITint, g_Config.fUISaturation);
Draw::DebugFlags debugFlags = Draw::DebugFlags::NONE;
if (g_Config.bShowGpuProfile)
debugFlags |= Draw::DebugFlags::PROFILE_TIMESTAMPS;
if (g_Config.bGpuLogProfiler)
debugFlags |= Draw::DebugFlags::PROFILE_SCOPES;
screenManager->getDrawContext()->SetDebugFlags(debugFlags);
g_screenManager->getDrawContext()->SetDebugFlags(debugFlags);
// All actual rendering happen in here.
screenManager->render();
if (screenManager->getUIContext()->Text()) {
screenManager->getUIContext()->Text()->OncePerFrame();
g_screenManager->render();
if (g_screenManager->getUIContext()->Text()) {
g_screenManager->getUIContext()->Text()->OncePerFrame();
}
if (resized) {
@@ -1142,7 +1137,7 @@ void NativeRender(GraphicsContext *graphicsContext) {
}
graphicsContext->Resize();
screenManager->resized();
g_screenManager->resized();
// TODO: Move this to the GraphicsContext objects for each backend.
#if !PPSSPP_PLATFORM(WINDOWS) && !defined(ANDROID)
@@ -1248,25 +1243,21 @@ void NativeUpdate() {
PROFILE_END_FRAME();
std::vector<PendingMessage> toProcess;
std::vector<PendingInputBox> inputToProcess;
{
std::lock_guard<std::mutex> lock(pendingMutex);
toProcess = std::move(pendingMessages);
inputToProcess = std::move(pendingInputBoxes);
pendingMessages.clear();
pendingInputBoxes.clear();
}
for (const auto &item : toProcess) {
HandleGlobalMessage(item.msg, item.value);
screenManager->sendMessage(item.msg.c_str(), item.value.c_str());
}
for (const auto &item : inputToProcess) {
item.cb(item.result, item.value);
g_screenManager->sendMessage(item.msg.c_str(), item.value.c_str());
}
g_requestManager.ProcessRequests();
g_DownloadManager.Update();
screenManager->update();
g_screenManager->update();
g_Discord.Update();
@@ -1275,11 +1266,11 @@ void NativeUpdate() {
bool NativeIsAtTopLevel() {
// This might need some synchronization?
if (!screenManager) {
if (!g_screenManager) {
ERROR_LOG(SYSTEM, "No screen manager active");
return false;
}
Screen *currentScreen = screenManager->topScreen();
Screen *currentScreen = g_screenManager->topScreen();
if (currentScreen) {
bool top = currentScreen->isTopLevel();
INFO_LOG(SYSTEM, "Screen toplevel: %i", (int)top);
@@ -1291,7 +1282,7 @@ bool NativeIsAtTopLevel() {
}
void NativeTouch(const TouchInput &touch) {
if (!screenManager) {
if (!g_screenManager) {
return;
}
@@ -1300,7 +1291,7 @@ void NativeTouch(const TouchInput &touch) {
if (my_isnan(touch.x) || my_isnan(touch.y)) {
return;
}
screenManager->touch(touch);
g_screenManager->touch(touch);
}
bool NativeKey(const KeyInput &key) {
@@ -1323,10 +1314,10 @@ bool NativeKey(const KeyInput &key) {
}
#endif
bool retval = false;
if (screenManager)
if (g_screenManager)
{
HLEPlugins::PluginDataKeys[key.keyCode] = (key.flags & KEY_DOWN) ? 1 : 0;
retval = screenManager->key(key);
retval = g_screenManager->key(key);
}
return retval;
}
@@ -1337,7 +1328,7 @@ void NativeAxis(const AxisInput &axis) {
return;
}
if (!screenManager) {
if (!g_screenManager) {
// Too early.
return;
}
@@ -1346,7 +1337,7 @@ void NativeAxis(const AxisInput &axis) {
// only do special handling of tilt events if tilt is enabled.
HLEPlugins::PluginDataAxis[axis.axisId] = axis.value;
screenManager->axis(axis);
g_screenManager->axis(axis);
if (g_Config.iTiltInputType == TILT_NULL) {
// if tilt events are disabled, don't do anything special.
@@ -1396,15 +1387,6 @@ void NativeMessageReceived(const char *message, const char *value) {
pendingMessages.push_back(pendingMessage);
}
void NativeInputBoxReceived(std::function<void(bool, const std::string &)> cb, bool result, const std::string &value) {
std::lock_guard<std::mutex> lock(pendingMutex);
PendingInputBox pendingMessage;
pendingMessage.cb = cb;
pendingMessage.result = result;
pendingMessage.value = value;
pendingInputBoxes.push_back(pendingMessage);
}
void NativeResized() {
// NativeResized can come from any thread so we just set a flag, then process it later.
VERBOSE_LOG(G3D, "NativeResized - setting flag");
@@ -1420,10 +1402,10 @@ bool NativeIsRestarting() {
}
void NativeShutdown() {
if (screenManager) {
screenManager->shutdown();
delete screenManager;
screenManager = nullptr;
if (g_screenManager) {
g_screenManager->shutdown();
delete g_screenManager;
g_screenManager = nullptr;
}
#if !PPSSPP_PLATFORM(UWP)
+3 -3
View File
@@ -31,6 +31,7 @@
#include "Common/Net/Resolve.h"
#include "Common/Net/URL.h"
#include "Common/Thread/ThreadUtil.h"
#include "Common/System/Request.h"
#include "Common/File/PathBrowser.h"
#include "Common/Data/Format/JSONReader.h"
@@ -38,7 +39,6 @@
#include "Common/Common.h"
#include "Common/Log.h"
#include "Common/StringUtils.h"
#include "Common/System/System.h"
#include "Common/TimeUtil.h"
#include "Core/Config.h"
#include "Core/System.h"
@@ -643,7 +643,7 @@ void RemoteISOSettingsScreen::CreateViews() {
UI::EventReturn RemoteISOSettingsScreen::OnClickRemoteServer(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__)
auto ri = GetI18NCategory("RemoteISO");
System_InputBoxGetString(ri->T("Remote Server"), g_Config.sLastRemoteISOServer, [](bool result, const std::string &value) {
System_InputBoxGetString(ri->T("Remote Server"), g_Config.sLastRemoteISOServer, [](const std::string &value, int) {
g_Config.sLastRemoteISOServer = value;
});
#endif
@@ -663,7 +663,7 @@ static void CleanupRemoteISOSubdir() {
UI::EventReturn RemoteISOSettingsScreen::OnClickRemoteISOSubdir(UI::EventParams &e) {
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__)
auto ri = GetI18NCategory("RemoteISO");
System_InputBoxGetString(ri->T("Remote Subdirectory"), g_Config.sRemoteISOSubdir, [](bool result, const std::string &value) {
System_InputBoxGetString(ri->T("Remote Subdirectory"), g_Config.sRemoteISOSubdir, [](const std::string &value, int) {
g_Config.sRemoteISOSubdir = value;
// Apply the cleanup logic, too.
CleanupRemoteISOSubdir();
+3 -3
View File
@@ -24,7 +24,7 @@
#include "Common/Data/Text/I18n.h"
#include "Common/Math/curves.h"
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/UI/Context.h"
#include "Common/UI/View.h"
@@ -674,8 +674,8 @@ UI::EventReturn SavedataScreen::OnSortClick(UI::EventParams &e) {
UI::EventReturn SavedataScreen::OnSearch(UI::EventParams &e) {
auto di = GetI18NCategory("Dialog");
#if PPSSPP_PLATFORM(WINDOWS) || defined(USING_QT_UI) || defined(__ANDROID__)
System_InputBoxGetString(di->T("Filter"), searchFilter_, [](bool result, const std::string &value) {
if (result) {
System_InputBoxGetString(di->T("Filter"), searchFilter_, [](const std::string &value, int ivalue) {
if (ivalue) {
NativeMessageReceived("savedatascreen_search", value.c_str());
}
});
+2
View File
@@ -376,6 +376,7 @@
<ClInclude Include="..\..\Common\SysError.h" />
<ClInclude Include="..\..\Common\System\Display.h" />
<ClInclude Include="..\..\Common\System\NativeApp.h" />
<ClInclude Include="..\..\Common\System\Request.h" />
<ClInclude Include="..\..\Common\System\System.h" />
<ClInclude Include="..\..\Common\Thread\Channel.h" />
<ClInclude Include="..\..\Common\Thread\Promise.h" />
@@ -510,6 +511,7 @@
<ClCompile Include="..\..\Common\OSVersion.cpp" />
<ClCompile Include="..\..\Common\StringUtils.cpp" />
<ClCompile Include="..\..\Common\System\Display.cpp" />
<ClCompile Include="..\..\Common\System\Request.cpp" />
<ClCompile Include="..\..\Common\Thread\ThreadUtil.cpp" />
<ClCompile Include="..\..\Common\Thread\ThreadManager.cpp" />
<ClCompile Include="..\..\Common\Thread\ParallelLoop.cpp" />
+6
View File
@@ -429,6 +429,9 @@
<ClCompile Include="..\..\ext\basis_universal\basisu_transcoder.cpp">
<Filter>ext\basis_universal</Filter>
</ClCompile>
<ClCompile Include="..\..\Common\System\Request.cpp">
<Filter>System</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="targetver.h" />
@@ -811,6 +814,9 @@
<ClInclude Include="..\..\ext\basis_universal\basisu_transcoder_uastc.h">
<Filter>ext\basis_universal</Filter>
</ClInclude>
<ClInclude Include="..\..\Common\System\Request.h">
<Filter>System</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\Common\Math\fast\fast_matrix_neon.S">
+2
View File
@@ -443,6 +443,8 @@ void System_Notify(SystemNotification notification) {
}
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) { return false; }
void System_SendMessage(const char *command, const char *parameter) {
using namespace concurrency;
-2
View File
@@ -107,7 +107,6 @@ struct VerySleepy_AddrInfo {
};
static std::wstring windowTitle;
extern ScreenManager *screenManager;
#define TIMER_CURSORUPDATE 1
#define TIMER_CURSORMOVEUPDATE 2
@@ -473,7 +472,6 @@ namespace MainWindow
}
void UpdateWindowTitle() {
// Seems to be fine to call now since we use a UNICODE build...
std::wstring title = windowTitle;
if (PPSSPP_ID >= 1 && GetInstancePeerCount() > 1) {
title.append(ConvertUTF8ToWString(StringFromFormat(" (instance: %d)", (int)PPSSPP_ID)));
+31 -23
View File
@@ -34,6 +34,7 @@
#include "Common/System/Display.h"
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/File/FileUtil.h"
#include "Common/File/VFS/VFS.h"
#include "Common/File/VFS/DirectoryReader.h"
@@ -109,8 +110,8 @@ static std::string restartArgs;
int g_activeWindow = 0;
static std::thread inputBoxThread;
static bool inputBoxRunning = false;
static std::thread g_inputBoxThread;
static bool g_inputBoxRunning = false;
int g_lastNumInstances = 0;
void System_ShowFileInFolder(const char *path) {
@@ -376,12 +377,13 @@ static BOOL PostDialogMessage(Dialog *dialog, UINT message, WPARAM wParam = 0, L
return PostMessage(dialog->GetDlgHandle(), message, wParam, lParam);
}
// This can come from any thread, so this mostly uses PostMessage. Can't access most data directly.
void System_Notify(SystemNotification notification) {
switch (notification) {
case SystemNotification::BOOT_DONE:
{
if (g_symbolMap)
g_symbolMap->SortSymbols();
g_symbolMap->SortSymbols(); // internal locking is performed here
PostMessage(MainWindow::GetHWND(), WM_USER + 1, 0, 0);
if (disasmWindow)
@@ -413,7 +415,7 @@ void System_Notify(SystemNotification notification) {
case SystemNotification::SYMBOL_MAP_UPDATED:
if (g_symbolMap)
g_symbolMap->SortSymbols();
g_symbolMap->SortSymbols(); // internal locking is performed here
PostMessage(MainWindow::GetHWND(), WM_USER + 1, 0, 0);
break;
@@ -428,6 +430,28 @@ void System_Notify(SystemNotification notification) {
}
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) {
switch (type) {
case SystemRequestType::INPUT_TEXT_MODAL:
if (g_inputBoxRunning) {
g_inputBoxThread.join();
}
g_inputBoxRunning = true;
g_inputBoxThread = std::thread([=] {
std::string out;
if (InputBox_GetString(MainWindow::GetHInstance(), MainWindow::GetHWND(), ConvertUTF8ToWString(param1).c_str(), param2, out)) {
g_requestManager.PostSystemSuccess(requestId, out.c_str());
} else {
g_requestManager.PostSystemFailure(requestId);
}
});
return true;
default:
return false;
}
}
void System_SendMessage(const char *command, const char *parameter) {
if (!strcmp(command, "finish")) {
if (!NativeIsRestarting()) {
@@ -497,22 +521,6 @@ void EnableCrashingOnCrashes() {
FreeLibrary(kernel32);
}
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) {
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);
@@ -619,9 +627,9 @@ static void WinMainInit() {
}
static void WinMainCleanup() {
if (inputBoxRunning) {
inputBoxThread.join();
inputBoxRunning = false;
if (g_inputBoxRunning) {
g_inputBoxThread.join();
g_inputBoxRunning = false;
}
net::Shutdown();
CoUninitialize();
+1
View File
@@ -214,6 +214,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Common/Net/WebsocketServer.cpp \
$(SRC)/Common/Profiler/Profiler.cpp \
$(SRC)/Common/System/Display.cpp \
$(SRC)/Common/System/Request.cpp \
$(SRC)/Common/Thread/ThreadUtil.cpp \
$(SRC)/Common/Thread/ThreadManager.cpp \
$(SRC)/Common/Thread/ParallelLoop.cpp \
+16 -16
View File
@@ -61,6 +61,7 @@ struct JNIEnv {};
#include "Common/System/Display.h"
#include "Common/System/NativeApp.h"
#include "Common/System/System.h"
#include "Common/System/Request.h"
#include "Common/Thread/ThreadUtil.h"
#include "Common/File/Path.h"
#include "Common/File/DirListing.h"
@@ -175,9 +176,6 @@ static std::atomic<bool> renderLoopRunning;
static bool renderer_inited = false;
static std::mutex renderLock;
static int inputBoxSequence = 1;
static std::map<int, std::function<void(bool, const std::string &)>> inputBoxCallbacks;
static bool sustainedPerfSupported = false;
static std::map<SystemPermission, PermissionStatus> permissions;
@@ -909,7 +907,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_shutdown(JNIEnv *, jclass) {
{
std::lock_guard<std::mutex> guard(renderLock);
inputBoxCallbacks.clear();
NativeShutdown();
g_VFS.Clear();
}
@@ -1032,12 +1029,17 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv
}
}
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) {
int seq = inputBoxSequence++;
inputBoxCallbacks[seq] = cb;
std::string serialized = StringFromFormat("%d:@:%s:@:%s", seq, title.c_str(), defaultValue.c_str());
System_SendMessage("inputbox", serialized.c_str());
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) {
switch (type) {
case SystemRequestType::INPUT_TEXT_MODAL:
{
std::string serialized = StringFromFormat("%d:@:%s:@:%s", requestId, param1.c_str(), param2.c_str());
PushCommand("inputbox", serialized.c_str());
return true;
}
default:
return false;
}
}
extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendInputBox(JNIEnv *env, jclass, jstring jseqID, jboolean result, jstring jvalue) {
@@ -1058,13 +1060,11 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_sendInputBox(JNIEnv *en
return;
}
auto entry = inputBoxCallbacks.find(seq);
if (entry == inputBoxCallbacks.end()) {
ERROR_LOG(SYSTEM, "Did not find inputbox callback for %s, shutdown?", seqID.c_str());
return;
if (result) {
g_requestManager.PostSystemSuccess(seq, value.c_str());
} else {
g_requestManager.PostSystemFailure(seq);
}
NativeInputBoxReceived(entry->second, result, value);
}
void LockedNativeUpdateRender() {
+1
View File
@@ -116,6 +116,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
}
void System_Notify(SystemNotification notification) {}
void System_SendMessage(const char *command, const char *parameter) {}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) { return false; }
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) { cb(false, ""); }
void System_AskForPermission(SystemPermission permission) {}
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }
+4
View File
@@ -219,6 +219,10 @@ void System_SendMessage(const char *command, const char *parameter) {
}
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) {
return false;
}
void System_Toast(const char *text) {}
void System_AskForPermission(SystemPermission permission) {}
+1
View File
@@ -341,6 +341,7 @@ SOURCES_CXX += \
$(COMMONDIR)/UI/ScrollView.cpp \
$(COMMONDIR)/UI/PopupScreens.cpp \
$(COMMONDIR)/System/Display.cpp \
$(COMMONDIR)/System/Request.cpp \
$(COMMONDIR)/ArmCPUDetect.cpp \
$(COMMONDIR)/CPUDetect.cpp \
$(COMMONDIR)/Buffer.cpp \
+1 -1
View File
@@ -1874,7 +1874,7 @@ void System_Notify(SystemNotification notification) {
break;
}
}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) { return false; }
void System_SendMessage(const char *command, const char *parameter) {}
void NativeUpdate() {}
void NativeRender(GraphicsContext *graphicsContext) {}
+1
View File
@@ -42,6 +42,7 @@ void NativeRender(GraphicsContext *graphicsContext) { }
void NativeResized() { }
void System_SendMessage(const char *command, const char *parameter) {}
bool System_MakeRequest(SystemRequestType type, int requestId, const std::string &param1, const std::string &param2) { return false; }
void System_InputBoxGetString(const std::string &title, const std::string &defaultValue, std::function<void(bool, const std::string &)> cb) { cb(false, ""); }
void System_AskForPermission(SystemPermission permission) {}
PermissionStatus System_GetPermissionStatus(SystemPermission permission) { return PERMISSION_STATUS_GRANTED; }