From ec993864fd49250c0fc57cd991e6d34d185b9200 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Sun, 21 Apr 2024 13:05:55 +0200 Subject: [PATCH] [ci skip] GameCardImageDumpOptionsFrame: add gamecard task subscription Lets us pop the frame itself from the view stack as soon as the gamecard is ejected. We're all about making this as fool-proof as possible. --- include/dump_options_frame.hpp | 4 +++- include/gamecard_image_dump_options_frame.hpp | 14 +++++++++++++ source/dump_options_frame.cpp | 2 +- source/error_frame.cpp | 2 +- source/gamecard_image_dump_options_frame.cpp | 21 +++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/dump_options_frame.hpp b/include/dump_options_frame.hpp index ec0941d..cfce7aa 100644 --- a/include/dump_options_frame.hpp +++ b/include/dump_options_frame.hpp @@ -32,8 +32,10 @@ namespace nxdt::views { class DumpOptionsFrame: public brls::ThumbnailFrame { - private: + protected: RootView *root_view = nullptr; + + private: std::string storage_prefix{}, base_output_path{}, raw_filename{}, extension{}; brls::List *list = nullptr; diff --git a/include/gamecard_image_dump_options_frame.hpp b/include/gamecard_image_dump_options_frame.hpp index 8ab4ab7..47f3f11 100644 --- a/include/gamecard_image_dump_options_frame.hpp +++ b/include/gamecard_image_dump_options_frame.hpp @@ -31,6 +31,9 @@ namespace nxdt::views class GameCardImageDumpOptionsFrame: public DumpOptionsFrame { private: + nxdt::tasks::GameCardStatusEvent::Subscription gc_task_sub; + brls::VoidEvent gc_ejected_event; + brls::ToggleListItem *prepend_key_area = nullptr; brls::ToggleListItem *keep_certificate = nullptr; brls::ToggleListItem *trim_dump = nullptr; @@ -39,6 +42,17 @@ namespace nxdt::views public: GameCardImageDumpOptionsFrame(RootView *root_view, std::string raw_filename); + ~GameCardImageDumpOptionsFrame(); + + ALWAYS_INLINE brls::VoidEvent::Subscription RegisterGameCardEjectionListener(brls::VoidEvent::Callback cb) + { + return this->gc_ejected_event.subscribe(cb); + } + + ALWAYS_INLINE void UnregisterGameCardEjectionListener(brls::VoidEvent::Subscription subscription) + { + this->gc_ejected_event.unsubscribe(subscription); + } }; } diff --git a/source/dump_options_frame.cpp b/source/dump_options_frame.cpp index 01583eb..974e9a4 100644 --- a/source/dump_options_frame.cpp +++ b/source/dump_options_frame.cpp @@ -50,7 +50,7 @@ namespace nxdt::views /* Unregister all button click event listeners. */ this->button_click_event->unsubscribeAll(); - /* Unregister task listener. */ + /* Unregister UMS task listener. */ this->root_view->UnregisterUmsTaskListener(this->ums_task_sub); } diff --git a/source/error_frame.cpp b/source/error_frame.cpp index 200443f..501df8c 100644 --- a/source/error_frame.cpp +++ b/source/error_frame.cpp @@ -26,7 +26,7 @@ namespace nxdt::views { - ErrorFrame::ErrorFrame(std::string msg): brls::View() + ErrorFrame::ErrorFrame(std::string msg) : brls::View() { this->label = new brls::Label(brls::LabelStyle::REGULAR, msg, true); this->label->setHorizontalAlign(NVG_ALIGN_CENTER); diff --git a/source/gamecard_image_dump_options_frame.cpp b/source/gamecard_image_dump_options_frame.cpp index ec7ed2b..aa58c30 100644 --- a/source/gamecard_image_dump_options_frame.cpp +++ b/source/gamecard_image_dump_options_frame.cpp @@ -29,6 +29,18 @@ namespace nxdt::views GameCardImageDumpOptionsFrame::GameCardImageDumpOptionsFrame(RootView *root_view, std::string raw_filename) : DumpOptionsFrame(root_view, "gamecard_tab/list/dump_card_image/label"_i18n, std::string(GAMECARD_SUBDIR), raw_filename, std::string(".xci")) { + /* Subscribe to the gamecard task event. */ + this->gc_task_sub = this->root_view->RegisterGameCardTaskListener([this](const GameCardStatus& gc_status) { + /* Realistically speaking, this should always match a NotInserted status, but it's always better to be safe than sorry. */ + if (gc_status != GameCardStatus_NotInserted) return; + + /* Fire gamecard ejection event. */ + this->gc_ejected_event.fire(); + + /* Pop view from stack immediately. */ + brls::Application::popView(); + }); + /* Prepend KeyArea data. */ this->prepend_key_area = new brls::ToggleListItem("dump_options/prepend_key_area/label"_i18n, configGetBoolean("gamecard/prepend_key_area"), "dump_options/prepend_key_area/description"_i18n, "generic/value_enabled"_i18n, "generic/value_disabled"_i18n); @@ -141,4 +153,13 @@ namespace nxdt::views LOG_MSG_DEBUG("Output file path: %s", this->GetOutputFilePath().c_str()); }); } + + GameCardImageDumpOptionsFrame::~GameCardImageDumpOptionsFrame() + { + /* Unregister all gamecard ejection event listeners. */ + this->gc_ejected_event.unsubscribeAll(); + + /* Unregister gamecard task listener. */ + this->root_view->UnregisterGameCardTaskListener(this->gc_task_sub); + } }