diff options
author | Zach Hilman <zachhilman@gmail.com> | 2018-11-19 20:24:36 +0100 |
---|---|---|
committer | Zach Hilman <zachhilman@gmail.com> | 2018-11-19 20:24:36 +0100 |
commit | 32775125b7af14cf488fdcbc4a61c00507c2d4a5 (patch) | |
tree | a63293691dff6b54c8fec47050f435118ed3a17e /src/core/hle/service/am/applets | |
parent | software_keyboard: Use correct offset for inital text string (diff) | |
download | yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar.gz yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar.bz2 yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar.lz yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar.xz yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.tar.zst yuzu-32775125b7af14cf488fdcbc4a61c00507c2d4a5.zip |
Diffstat (limited to 'src/core/hle/service/am/applets')
-rw-r--r-- | src/core/hle/service/am/applets/applets.cpp | 95 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/applets.h | 56 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/software_keyboard.cpp | 43 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/software_keyboard.h | 12 |
4 files changed, 159 insertions, 47 deletions
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index be950d320..c81bd59b2 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -4,21 +4,108 @@ #include <cstring> #include "common/assert.h" +#include "core/core.h" #include "core/frontend/applets/software_keyboard.h" +#include "core/hle/kernel/event.h" +#include "core/hle/kernel/server_port.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/applets.h" namespace Service::AM::Applets { +AppletDataBroker::AppletDataBroker() { + auto& kernel = Core::System::GetInstance().Kernel(); + state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, + "ILibraryAppletAccessor:StateChangedEvent"); + pop_out_data_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, + "ILibraryAppletAccessor:PopDataOutEvent"); + pop_interactive_out_data_event = Kernel::Event::Create( + kernel, Kernel::ResetType::OneShot, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); +} + +AppletDataBroker::~AppletDataBroker() = default; + +std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { + if (out_channel.empty()) + return nullptr; + + auto out = std::move(out_channel.front()); + out_channel.pop(); + return out; +} + +std::unique_ptr<IStorage> AppletDataBroker::PopNormalDataToApplet() { + if (in_channel.empty()) + return nullptr; + + auto out = std::move(in_channel.front()); + in_channel.pop(); + return out; +} + +std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { + if (out_interactive_channel.empty()) + return nullptr; + + auto out = std::move(out_interactive_channel.front()); + out_interactive_channel.pop(); + return out; +} + +std::unique_ptr<IStorage> AppletDataBroker::PopInteractiveDataToApplet() { + if (in_interactive_channel.empty()) + return nullptr; + + auto out = std::move(in_interactive_channel.front()); + in_interactive_channel.pop(); + return out; +} + +void AppletDataBroker::PushNormalDataFromGame(IStorage storage) { + in_channel.push(std::make_unique<IStorage>(storage)); +} + +void AppletDataBroker::PushNormalDataFromApplet(IStorage storage) { + out_channel.push(std::make_unique<IStorage>(storage)); + pop_out_data_event->Signal(); +} + +void AppletDataBroker::PushInteractiveDataFromGame(IStorage storage) { + in_interactive_channel.push(std::make_unique<IStorage>(storage)); +} + +void AppletDataBroker::PushInteractiveDataFromApplet(IStorage storage) { + out_interactive_channel.push(std::make_unique<IStorage>(storage)); + pop_interactive_out_data_event->Signal(); +} + +void AppletDataBroker::SignalStateChanged() const { + state_changed_event->Signal(); +} + +Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetNormalDataEvent() const { + return pop_out_data_event; +} + +Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetInteractiveDataEvent() const { + return pop_interactive_out_data_event; +} + +Kernel::SharedPtr<Kernel::Event> AppletDataBroker::GetStateChangedEvent() const { + return state_changed_event; +} + Applet::Applet() = default; Applet::~Applet() = default; -void Applet::Initialize(std::queue<std::shared_ptr<IStorage>> storage) { - storage_stack = std::move(storage); +void Applet::Initialize(std::shared_ptr<AppletDataBroker> broker_) { + broker = std::move(broker_); + + const auto common = broker->PopNormalDataToApplet(); + ASSERT(common != nullptr); - const auto common_data = storage_stack.front()->GetData(); - storage_stack.pop(); + const auto common_data = common->GetData(); ASSERT(common_data.size() >= sizeof(CommonArguments)); std::memcpy(&common_args, common_data.data(), sizeof(CommonArguments)); diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index a6a9bf77b..136445649 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -8,35 +8,67 @@ #include <memory> #include <queue> #include "common/swap.h" +#include "core/hle/kernel/event.h" union ResultCode; -namespace Frontend { -class SoftwareKeyboardApplet; -} - namespace Service::AM { class IStorage; namespace Applets { -using AppletStorageProxyFunction = std::function<void(IStorage)>; -using AppletStateProxyFunction = std::function<void()>; +class AppletDataBroker final { +public: + AppletDataBroker(); + ~AppletDataBroker(); + + std::unique_ptr<IStorage> PopNormalDataToGame(); + std::unique_ptr<IStorage> PopNormalDataToApplet(); + + std::unique_ptr<IStorage> PopInteractiveDataToGame(); + std::unique_ptr<IStorage> PopInteractiveDataToApplet(); + + void PushNormalDataFromGame(IStorage storage); + void PushNormalDataFromApplet(IStorage storage); + + void PushInteractiveDataFromGame(IStorage storage); + void PushInteractiveDataFromApplet(IStorage storage); + + void SignalStateChanged() const; + + Kernel::SharedPtr<Kernel::Event> GetNormalDataEvent() const; + Kernel::SharedPtr<Kernel::Event> GetInteractiveDataEvent() const; + Kernel::SharedPtr<Kernel::Event> GetStateChangedEvent() const; + +private: + // Queues are named from applet's perspective + std::queue<std::unique_ptr<IStorage>> + in_channel; // PopNormalDataToApplet and PushNormalDataFromGame + std::queue<std::unique_ptr<IStorage>> + out_channel; // PopNormalDataToGame and PushNormalDataFromApplet + std::queue<std::unique_ptr<IStorage>> + in_interactive_channel; // PopInteractiveDataToApplet and PushInteractiveDataFromGame + std::queue<std::unique_ptr<IStorage>> + out_interactive_channel; // PopInteractiveDataToGame and PushInteractiveDataFromApplet + + Kernel::SharedPtr<Kernel::Event> state_changed_event; + Kernel::SharedPtr<Kernel::Event> pop_out_data_event; // Signaled on PushNormalDataFromApplet + Kernel::SharedPtr<Kernel::Event> + pop_interactive_out_data_event; // Signaled on PushInteractiveDataFromApplet +}; class Applet { public: Applet(); virtual ~Applet(); - virtual void Initialize(std::queue<std::shared_ptr<IStorage>> storage); + virtual void Initialize(std::shared_ptr<AppletDataBroker> broker); virtual bool TransactionComplete() const = 0; virtual ResultCode GetStatus() const = 0; - virtual void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) = 0; - virtual void Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data, - AppletStateProxyFunction state) = 0; + virtual void ExecuteInteractive() = 0; + virtual void Execute() = 0; bool IsInitialized() const { return initialized; @@ -54,7 +86,7 @@ protected: static_assert(sizeof(CommonArguments) == 0x20, "CommonArguments has incorrect size."); CommonArguments common_args; - std::queue<std::shared_ptr<IStorage>> storage_stack; + std::shared_ptr<AppletDataBroker> broker; bool initialized = false; }; diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index 816b5fb5f..ca9ef7e7d 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -42,22 +42,23 @@ SoftwareKeyboard::SoftwareKeyboard() = default; SoftwareKeyboard::~SoftwareKeyboard() = default; -void SoftwareKeyboard::Initialize(std::queue<std::shared_ptr<IStorage>> storage_) { +void SoftwareKeyboard::Initialize(std::shared_ptr<AppletDataBroker> broker_) { complete = false; initial_text.clear(); final_data.clear(); - Applet::Initialize(std::move(storage_)); + Applet::Initialize(std::move(broker_)); - ASSERT(storage_stack.size() >= 2); - const auto& keyboard_config = storage_stack.front()->GetData(); - storage_stack.pop(); + const auto keyboard_config_storage = broker->PopNormalDataToApplet(); + ASSERT(keyboard_config_storage != nullptr); + const auto& keyboard_config = keyboard_config_storage->GetData(); ASSERT(keyboard_config.size() >= sizeof(KeyboardConfig)); std::memcpy(&config, keyboard_config.data(), sizeof(KeyboardConfig)); - const auto& work_buffer = storage_stack.front()->GetData(); - storage_stack.pop(); + const auto work_buffer_storage = broker->PopNormalDataToApplet(); + ASSERT(work_buffer_storage != nullptr); + const auto& work_buffer = work_buffer_storage->GetData(); if (config.initial_string_size == 0) return; @@ -76,10 +77,12 @@ ResultCode SoftwareKeyboard::GetStatus() const { return status; } -void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage) { +void SoftwareKeyboard::ExecuteInteractive() { if (complete) return; + const auto storage = broker->PopInteractiveDataToApplet(); + ASSERT(storage != nullptr); const auto data = storage->GetData(); const auto status = static_cast<bool>(data[0]); @@ -91,15 +94,14 @@ void SoftwareKeyboard::ReceiveInteractiveData(std::shared_ptr<IStorage> storage) std::array<char16_t, SWKBD_OUTPUT_INTERACTIVE_BUFFER_SIZE / 2 - 2> string; std::memcpy(string.data(), data.data() + 4, string.size() * 2); frontend.SendTextCheckDialog( - Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()), state); + Common::UTF16StringFromFixedZeroTerminatedBuffer(string.data(), string.size()), + [this] { broker->SignalStateChanged(); }); } } -void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data, - AppletStateProxyFunction state) { +void SoftwareKeyboard::Execute() { if (complete) { - out_data(IStorage{final_data}); + broker->PushNormalDataFromApplet(IStorage{final_data}); return; } @@ -107,9 +109,6 @@ void SoftwareKeyboard::Execute(AppletStorageProxyFunction out_data, const auto parameters = ConvertToFrontendParameters(config, initial_text); - this->out_data = out_data; - this->out_interactive_data = out_interactive_data; - this->state = state; frontend.RequestText([this](std::optional<std::u16string> text) { WriteText(text); }, parameters); } @@ -147,19 +146,19 @@ void SoftwareKeyboard::WriteText(std::optional<std::u16string> text) { final_data = output_main; if (complete) { - out_data(IStorage{output_main}); + broker->PushNormalDataFromApplet(IStorage{output_main}); } else { - out_data(IStorage{output_main}); - out_interactive_data(IStorage{output_sub}); + broker->PushNormalDataFromApplet(IStorage{output_main}); + broker->PushInteractiveDataFromApplet(IStorage{output_sub}); } - state(); + broker->SignalStateChanged(); } else { status = ResultCode(-1); output_main[0] = 1; complete = true; - out_data(IStorage{output_main}); - state(); + broker->PushNormalDataFromApplet(IStorage{output_main}); + broker->SignalStateChanged(); } } } // namespace Service::AM::Applets diff --git a/src/core/hle/service/am/applets/software_keyboard.h b/src/core/hle/service/am/applets/software_keyboard.h index e0a9479c2..405c58851 100644 --- a/src/core/hle/service/am/applets/software_keyboard.h +++ b/src/core/hle/service/am/applets/software_keyboard.h @@ -50,14 +50,12 @@ public: SoftwareKeyboard(); ~SoftwareKeyboard() override; - void Initialize(std::queue<std::shared_ptr<IStorage>> storage) override; + void Initialize(std::shared_ptr<AppletDataBroker> broker) override; bool TransactionComplete() const override; ResultCode GetStatus() const override; - void ReceiveInteractiveData(std::shared_ptr<IStorage> storage) override; - void Execute(AppletStorageProxyFunction out_data, - AppletStorageProxyFunction out_interactive_data, - AppletStateProxyFunction state) override; + void ExecuteInteractive() override; + void Execute() override; void WriteText(std::optional<std::u16string> text); @@ -67,10 +65,6 @@ private: bool complete = false; std::vector<u8> final_data; ResultCode status = ResultCode(-1); - - AppletStorageProxyFunction out_data; - AppletStorageProxyFunction out_interactive_data; - AppletStateProxyFunction state; }; } // namespace Service::AM::Applets |