am: Allow applets to push multiple and different channels of data

This commit is contained in:
Zach Hilman 2018-11-11 20:16:38 -05:00
parent 3cf7246e37
commit 7cfb29de23
10 changed files with 62 additions and 64 deletions

View file

@ -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 {

View file

@ -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;
}; };

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;
} }

View file

@ -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:

View file

@ -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);

View file

@ -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: