mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-24 10:23:01 -06:00
am: Allow applets to push multiple and different channels of data
This commit is contained in:
parent
3cf7246e37
commit
7cfb29de23
10 changed files with 62 additions and 64 deletions
|
@ -9,14 +9,12 @@
|
||||||
namespace Core::Frontend {
|
namespace Core::Frontend {
|
||||||
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
|
SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
|
||||||
|
|
||||||
bool DefaultSoftwareKeyboardApplet::GetText(SoftwareKeyboardParameters parameters,
|
std::optional<std::u16string> DefaultSoftwareKeyboardApplet::GetText(
|
||||||
std::u16string& text) const {
|
SoftwareKeyboardParameters parameters) const {
|
||||||
if (parameters.initial_text.empty())
|
if (parameters.initial_text.empty())
|
||||||
text = u"yuzu";
|
return u"yuzu";
|
||||||
else
|
|
||||||
text = parameters.initial_text;
|
|
||||||
|
|
||||||
return true;
|
return parameters.initial_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(std::u16string error_message) const {
|
void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(std::u16string error_message) const {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -35,13 +36,13 @@ class SoftwareKeyboardApplet {
|
||||||
public:
|
public:
|
||||||
virtual ~SoftwareKeyboardApplet();
|
virtual ~SoftwareKeyboardApplet();
|
||||||
|
|
||||||
virtual bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const = 0;
|
virtual std::optional<std::u16string> GetText(SoftwareKeyboardParameters parameters) const = 0;
|
||||||
virtual void SendTextCheckDialog(std::u16string error_message) const = 0;
|
virtual void SendTextCheckDialog(std::u16string error_message) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
|
class DefaultSoftwareKeyboardApplet final : public SoftwareKeyboardApplet {
|
||||||
public:
|
public:
|
||||||
bool GetText(SoftwareKeyboardParameters parameters, std::u16string& text) const override;
|
std::optional<std::u16string> GetText(SoftwareKeyboardParameters parameters) const override;
|
||||||
void SendTextCheckDialog(std::u16string error_message) const override;
|
void SendTextCheckDialog(std::u16string error_message) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -566,6 +566,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void AppletStorageProxyOutData(IStorage storage) {
|
||||||
|
storage_stack.push_back(std::make_shared<IStorage>(storage));
|
||||||
|
pop_out_data_event->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletStorageProxyOutInteractiveData(IStorage storage) {
|
||||||
|
interactive_storage_stack.push_back(std::make_shared<IStorage>(storage));
|
||||||
|
pop_interactive_out_data_event->Signal();
|
||||||
|
}
|
||||||
|
|
||||||
void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
|
void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
|
||||||
state_changed_event->Signal();
|
state_changed_event->Signal();
|
||||||
|
|
||||||
|
@ -591,17 +601,11 @@ private:
|
||||||
ASSERT(applet != nullptr);
|
ASSERT(applet != nullptr);
|
||||||
|
|
||||||
applet->Initialize(storage_stack);
|
applet->Initialize(storage_stack);
|
||||||
const auto data = std::make_shared<IStorage>(applet->Execute());
|
applet->Execute(
|
||||||
|
[this](IStorage storage) { AppletStorageProxyOutData(storage); },
|
||||||
|
[this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); });
|
||||||
state_changed_event->Signal();
|
state_changed_event->Signal();
|
||||||
|
|
||||||
if (applet->TransactionComplete()) {
|
|
||||||
storage_stack.push_back(data);
|
|
||||||
pop_out_data_event->Signal();
|
|
||||||
} else {
|
|
||||||
interactive_storage_stack.push_back(data);
|
|
||||||
pop_interactive_out_data_event->Signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
@ -632,17 +636,11 @@ private:
|
||||||
|
|
||||||
ASSERT(applet->IsInitialized());
|
ASSERT(applet->IsInitialized());
|
||||||
applet->ReceiveInteractiveData(interactive_storage_stack.back());
|
applet->ReceiveInteractiveData(interactive_storage_stack.back());
|
||||||
const auto data = std::make_shared<IStorage>(applet->Execute());
|
applet->Execute(
|
||||||
|
[this](IStorage storage) { AppletStorageProxyOutData(storage); },
|
||||||
|
[this](IStorage storage) { AppletStorageProxyOutInteractiveData(storage); });
|
||||||
state_changed_event->Signal();
|
state_changed_event->Signal();
|
||||||
|
|
||||||
if (applet->TransactionComplete()) {
|
|
||||||
storage_stack.push_back(data);
|
|
||||||
pop_out_data_event->Signal();
|
|
||||||
} else {
|
|
||||||
interactive_storage_stack.push_back(data);
|
|
||||||
pop_interactive_out_data_event->Signal();
|
|
||||||
}
|
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
|
@ -20,6 +21,8 @@ class IStorage;
|
||||||
|
|
||||||
namespace Applets {
|
namespace Applets {
|
||||||
|
|
||||||
|
using AppletStorageProxyFunction = std::function<void(IStorage)>;
|
||||||
|
|
||||||
class Applet {
|
class Applet {
|
||||||
public:
|
public:
|
||||||
Applet();
|
Applet();
|
||||||
|
@ -30,7 +33,8 @@ public:
|
||||||
virtual bool TransactionComplete() const = 0;
|
virtual bool TransactionComplete() const = 0;
|
||||||
virtual ResultCode GetStatus() const = 0;
|
virtual ResultCode GetStatus() const = 0;
|
||||||
virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0;
|
virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0;
|
||||||
virtual IStorage Execute() = 0;
|
virtual void Execute(AppletStorageProxyFunction out_data,
|
||||||
|
AppletStorageProxyFunction out_interactive_data) = 0;
|
||||||
|
|
||||||
bool IsInitialized() const {
|
bool IsInitialized() const {
|
||||||
return initialized;
|
return initialized;
|
||||||
|
|
|
@ -87,42 +87,37 @@ void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IStorage SoftwareKeyboard::Execute() {
|
void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data,
|
||||||
|
AppletStorageProxyFunction out_interactive_data) {
|
||||||
if (complete)
|
if (complete)
|
||||||
return IStorage{final_data};
|
return;
|
||||||
|
|
||||||
const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()};
|
const auto& frontend{Core::System::GetInstance().GetSoftwareKeyboard()};
|
||||||
|
|
||||||
const auto parameters = ConvertToFrontendParameters(config, initial_text);
|
const auto parameters = ConvertToFrontendParameters(config, initial_text);
|
||||||
|
|
||||||
std::u16string text;
|
const auto res = frontend.GetText(parameters);
|
||||||
const auto success = frontend.GetText(parameters, text);
|
|
||||||
|
|
||||||
std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE);
|
std::vector<u8> output(SWKBD_OUTPUT_BUFFER_SIZE);
|
||||||
|
|
||||||
if (success) {
|
if (res.has_value()) {
|
||||||
if (config.text_check) {
|
if (config.text_check) {
|
||||||
const auto size = static_cast<u32>(text.size() * 2 + 4);
|
const auto size = static_cast<u32>(res->size() * 2 + 4);
|
||||||
std::memcpy(output.data(), &size, sizeof(u32));
|
std::memcpy(output.data(), &size, sizeof(u32));
|
||||||
} else {
|
} else {
|
||||||
output[0] = 1;
|
output[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memcpy(output.data() + 4, text.data(),
|
std::memcpy(output.data() + 4, res->data(),
|
||||||
std::min(text.size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
|
std::min(res->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
|
||||||
} else {
|
} else {
|
||||||
complete = true;
|
complete = true;
|
||||||
final_data = std::move(output);
|
out_data(IStorage{output});
|
||||||
return IStorage{final_data};
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
complete = !config.text_check;
|
complete = !config.text_check;
|
||||||
|
|
||||||
if (complete) {
|
(complete ? out_data : out_interactive_data)(IStorage{output});
|
||||||
final_data = std::move(output);
|
|
||||||
return IStorage{final_data};
|
|
||||||
}
|
|
||||||
|
|
||||||
return IStorage{output};
|
|
||||||
}
|
}
|
||||||
} // namespace Service::AM::Applets
|
} // namespace Service::AM::Applets
|
||||||
|
|
|
@ -54,7 +54,8 @@ public:
|
||||||
bool TransactionComplete() const override;
|
bool TransactionComplete() const override;
|
||||||
ResultCode GetStatus() const override;
|
ResultCode GetStatus() const override;
|
||||||
void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override;
|
void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override;
|
||||||
IStorage Execute() override;
|
void Execute(AppletStorageProxyFunction out_data,
|
||||||
|
AppletStorageProxyFunction out_interactive_data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeyboardConfig config;
|
KeyboardConfig config;
|
||||||
|
|
|
@ -97,11 +97,11 @@ void QtSoftwareKeyboardDialog::Reject() {
|
||||||
accept();
|
accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::u16string QtSoftwareKeyboardDialog::GetText() {
|
std::u16string QtSoftwareKeyboardDialog::GetText() const {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QtSoftwareKeyboardDialog::GetStatus() {
|
bool QtSoftwareKeyboardDialog::GetStatus() const {
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,13 +109,12 @@ QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& parent) : main_window(parent
|
||||||
|
|
||||||
QtSoftwareKeyboard::~QtSoftwareKeyboard() = default;
|
QtSoftwareKeyboard::~QtSoftwareKeyboard() = default;
|
||||||
|
|
||||||
bool QtSoftwareKeyboard::GetText(Core::Frontend::SoftwareKeyboardParameters parameters,
|
std::optional<std::u16string> QtSoftwareKeyboard::GetText(
|
||||||
std::u16string& text) const {
|
Core::Frontend::SoftwareKeyboardParameters parameters) const {
|
||||||
bool success;
|
std::optional<std::u16string> success;
|
||||||
QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardGetText", Qt::BlockingQueuedConnection,
|
QMetaObject::invokeMethod(&main_window, "SoftwareKeyboardGetText", Qt::BlockingQueuedConnection,
|
||||||
Q_RETURN_ARG(bool, success),
|
Q_RETURN_ARG(std::optional<std::u16string>, success),
|
||||||
Q_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters),
|
Q_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters));
|
||||||
Q_ARG(std::u16string&, text));
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ public:
|
||||||
void Submit();
|
void Submit();
|
||||||
void Reject();
|
void Reject();
|
||||||
|
|
||||||
std::u16string GetText();
|
std::u16string GetText() const;
|
||||||
bool GetStatus();
|
bool GetStatus() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
@ -58,8 +58,8 @@ public:
|
||||||
explicit QtSoftwareKeyboard(GMainWindow& parent);
|
explicit QtSoftwareKeyboard(GMainWindow& parent);
|
||||||
~QtSoftwareKeyboard() override;
|
~QtSoftwareKeyboard() override;
|
||||||
|
|
||||||
bool GetText(Core::Frontend::SoftwareKeyboardParameters parameters,
|
std::optional<std::u16string> GetText(
|
||||||
std::u16string& text) const override;
|
Core::Frontend::SoftwareKeyboardParameters parameters) const override;
|
||||||
void SendTextCheckDialog(std::u16string error_message) const override;
|
void SendTextCheckDialog(std::u16string error_message) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -207,16 +207,18 @@ GMainWindow::~GMainWindow() {
|
||||||
delete render_window;
|
delete render_window;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GMainWindow::SoftwareKeyboardGetText(
|
std::optional<std::u16string> GMainWindow::SoftwareKeyboardGetText(
|
||||||
const Core::Frontend::SoftwareKeyboardParameters& parameters, std::u16string& text) {
|
const Core::Frontend::SoftwareKeyboardParameters& parameters) {
|
||||||
QtSoftwareKeyboardDialog dialog(this, parameters);
|
QtSoftwareKeyboardDialog dialog(this, parameters);
|
||||||
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
|
||||||
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
|
||||||
dialog.setWindowModality(Qt::WindowModal);
|
dialog.setWindowModality(Qt::WindowModal);
|
||||||
dialog.exec();
|
dialog.exec();
|
||||||
|
|
||||||
text = dialog.GetText();
|
if (!dialog.GetStatus())
|
||||||
return dialog.GetStatus();
|
return std::nullopt;
|
||||||
|
|
||||||
|
return dialog.GetText();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) {
|
void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message) {
|
||||||
|
@ -1251,10 +1253,10 @@ void GMainWindow::OnStartGame() {
|
||||||
emu_thread->SetRunning(true);
|
emu_thread->SetRunning(true);
|
||||||
|
|
||||||
qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
|
qRegisterMetaType<Core::Frontend::SoftwareKeyboardParameters>(
|
||||||
"core::Frontend::SoftwareKeyboardParameters");
|
"Core::Frontend::SoftwareKeyboardParameters");
|
||||||
qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
|
qRegisterMetaType<Core::System::ResultStatus>("Core::System::ResultStatus");
|
||||||
qRegisterMetaType<std::string>("std::string");
|
qRegisterMetaType<std::string>("std::string");
|
||||||
qRegisterMetaType<std::u16string>("std::u16string");
|
qRegisterMetaType<std::optional<std::u16string>>("std::optional<std::u16string>");
|
||||||
|
|
||||||
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
|
connect(emu_thread.get(), &EmuThread::ErrorThrown, this, &GMainWindow::OnCoreError);
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ signals:
|
||||||
void UpdateThemedIcons();
|
void UpdateThemedIcons();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters,
|
std::optional<std::u16string> SoftwareKeyboardGetText(
|
||||||
std::u16string& text);
|
const Core::Frontend::SoftwareKeyboardParameters& parameters);
|
||||||
void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
|
void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue