Przeglądaj źródła

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

Zach Hilman 7 lat temu
rodzic
commit
7cfb29de23

+ 4 - 6
src/core/frontend/applets/software_keyboard.cpp

@@ -9,14 +9,12 @@
 namespace Core::Frontend {
 namespace Core::Frontend {
 SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
 SoftwareKeyboardApplet::~SoftwareKeyboardApplet() = default;
 
 
-bool DefaultSoftwareKeyboardApplet::GetText(SoftwareKeyboardParameters parameters,
-                                            std::u16string& text) const {
+std::optional<std::u16string> DefaultSoftwareKeyboardApplet::GetText(
+    SoftwareKeyboardParameters parameters) const {
     if (parameters.initial_text.empty())
     if (parameters.initial_text.empty())
-        text = u"yuzu";
-    else
-        text = parameters.initial_text;
+        return u"yuzu";
 
 
-    return true;
+    return parameters.initial_text;
 }
 }
 
 
 void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(std::u16string error_message) const {
 void DefaultSoftwareKeyboardApplet::SendTextCheckDialog(std::u16string error_message) const {

+ 3 - 2
src/core/frontend/applets/software_keyboard.h

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

+ 16 - 18
src/core/hle/service/am/am.cpp

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

+ 5 - 1
src/core/hle/service/am/applets/applets.h

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

+ 11 - 16
src/core/hle/service/am/applets/software_keyboard.cpp

@@ -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 success = frontend.GetText(parameters, text);
+    const auto res = frontend.GetText(parameters);
 
 
     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::min(text.size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
+        std::memcpy(output.data() + 4, res->data(),
+                    std::min(res->size() * 2, SWKBD_OUTPUT_BUFFER_SIZE - 4));
     } else {
     } else {
         complete = true;
         complete = true;
-        final_data = std::move(output);
-        return IStorage{final_data};
+        out_data(IStorage{output});
+        return;
     }
     }
 
 
     complete = !config.text_check;
     complete = !config.text_check;
 
 
-    if (complete) {
-        final_data = std::move(output);
-        return IStorage{final_data};
-    }
-
-    return IStorage{output};
+    (complete ? out_data : out_interactive_data)(IStorage{output});
 }
 }
 } // namespace Service::AM::Applets
 } // namespace Service::AM::Applets

+ 2 - 1
src/core/hle/service/am/applets/software_keyboard.h

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

+ 7 - 8
src/yuzu/applets/software_keyboard.cpp

@@ -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::u16string& text) const {
-    bool success;
+std::optional<std::u16string> QtSoftwareKeyboard::GetText(
+    Core::Frontend::SoftwareKeyboardParameters parameters) const {
+    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_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters),
-                              Q_ARG(std::u16string&, text));
+                              Q_RETURN_ARG(std::optional<std::u16string>, success),
+                              Q_ARG(Core::Frontend::SoftwareKeyboardParameters, parameters));
     return success;
     return success;
 }
 }
 
 

+ 4 - 4
src/yuzu/applets/software_keyboard.h

@@ -36,8 +36,8 @@ public:
     void Submit();
     void Submit();
     void Reject();
     void Reject();
 
 
-    std::u16string GetText();
-    bool GetStatus();
+    std::u16string GetText() const;
+    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::u16string& text) const override;
+    std::optional<std::u16string> GetText(
+        Core::Frontend::SoftwareKeyboardParameters parameters) const override;
     void SendTextCheckDialog(std::u16string error_message) const override;
     void SendTextCheckDialog(std::u16string error_message) const override;
 
 
 private:
 private:

+ 8 - 6
src/yuzu/main.cpp

@@ -207,16 +207,18 @@ GMainWindow::~GMainWindow() {
         delete render_window;
         delete render_window;
 }
 }
 
 
-bool GMainWindow::SoftwareKeyboardGetText(
-    const Core::Frontend::SoftwareKeyboardParameters& parameters, std::u16string& text) {
+std::optional<std::u16string> GMainWindow::SoftwareKeyboardGetText(
+    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();
-    return dialog.GetStatus();
+    if (!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);
 
 

+ 2 - 2
src/yuzu/main.h

@@ -100,8 +100,8 @@ signals:
     void UpdateThemedIcons();
     void UpdateThemedIcons();
 
 
 public slots:
 public slots:
-    bool SoftwareKeyboardGetText(const Core::Frontend::SoftwareKeyboardParameters& parameters,
-                                 std::u16string& text);
+    std::optional<std::u16string> SoftwareKeyboardGetText(
+        const Core::Frontend::SoftwareKeyboardParameters& parameters);
     void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
     void SoftwareKeyboardInvokeCheckDialog(std::u16string error_message);
 
 
 private:
 private: