summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/am/applets
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-11-19 20:24:36 +0100
committerZach Hilman <zachhilman@gmail.com>2018-11-19 20:24:36 +0100
commit32775125b7af14cf488fdcbc4a61c00507c2d4a5 (patch)
treea63293691dff6b54c8fec47050f435118ed3a17e /src/core/hle/service/am/applets
parentsoftware_keyboard: Use correct offset for inital text string (diff)
downloadyuzu-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.cpp95
-rw-r--r--src/core/hle/service/am/applets/applets.h56
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp43
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.h12
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