From 06676a063905a24e2bd5ef468f6061e9c787a0a6 Mon Sep 17 00:00:00 2001 From: Pablo Curiel Date: Thu, 10 Jun 2021 20:33:11 -0400 Subject: [PATCH] tasks: cache application metadata and UMS device info using vectors. * Tasks are now immediately started by their constructor function. * Events are now part of the class of each task type, in order to avoid instantiating each one of them and passing them as a constructor argument. * GetTaskEvent() has been added to each task class, which returns a pointer to the private event. This will be used to subscribe Borealis views to a particular event. * Title and UMS tasks now both cache application metadata and UMS device info using private vectors. Pointers to these private vectors can now be retrieved using public functions GetApplicationMetadata() and GetUmsDevices(), respectively. --- include/tasks.hpp | 57 ++++++++++++++--- source/main.cpp | 34 ++++------- source/tasks.cpp | 153 ++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 194 insertions(+), 50 deletions(-) diff --git a/include/tasks.hpp b/include/tasks.hpp index 19be79d..0e9be9d 100644 --- a/include/tasks.hpp +++ b/include/tasks.hpp @@ -38,48 +38,85 @@ namespace nxdt::tasks typedef brls::VoidEvent VoidEvent; typedef brls::Event BooleanEvent; + /* Custom vector type used to hold pointers to application metadata entries. */ + typedef std::vector TitleApplicationMetadataVector; + + /* Custom vector type used to hold UMS devices. */ + typedef std::vector UmsDeviceVector; + /* Gamecard task. */ class GameCardTask: public brls::RepeatingTask { private: + GameCardStatusEvent gc_status_event; + GameCardStatus cur_gc_status = GameCardStatus_NotInserted; GameCardStatus prev_gc_status = GameCardStatus_NotInserted; - GameCardStatusEvent *gc_status_event = nullptr; public: - GameCardTask(GameCardStatusEvent *gc_status_event); + GameCardTask(void); + ~GameCardTask(void); + void run(retro_time_t current_time) override; + + GameCardStatusEvent* GetTaskEvent(void); }; - /* Gamecard title task. */ - class GameCardTitleTask: public brls::RepeatingTask + /* Title task. */ + class TitleTask: public brls::RepeatingTask { private: - VoidEvent *gc_title_event = nullptr; + VoidEvent title_event; + + TitleApplicationMetadataVector system_metadata; + TitleApplicationMetadataVector user_metadata; + + void PopulateApplicationMetadataVector(bool is_system); public: - GameCardTitleTask(VoidEvent *gc_title_event); + TitleTask(void); + ~TitleTask(void); + void run(retro_time_t current_time) override; + + VoidEvent* GetTaskEvent(void); + + TitleApplicationMetadataVector* GetApplicationMetadata(bool is_system); }; /* USB Mass Storage task. */ class UmsTask: public brls::RepeatingTask { private: - VoidEvent *ums_event = nullptr; + VoidEvent ums_event; + + UmsDeviceVector ums_devices; + + void PopulateUmsDeviceVector(void); public: - UmsTask(VoidEvent *ums_event); + UmsTask(void); + ~UmsTask(void); + void run(retro_time_t current_time) override; + + VoidEvent* GetTaskEvent(void); + + UmsDeviceVector* GetUmsDevices(void); }; /* USB host device connection task. */ class UsbHostTask: public brls::RepeatingTask { private: + BooleanEvent usb_host_event; + bool cur_usb_host_status = false; bool prev_usb_host_status = false; - BooleanEvent *usb_host_event = nullptr; public: - UsbHostTask(BooleanEvent *usb_host_event); + UsbHostTask(void); + ~UsbHostTask(void); + void run(retro_time_t current_time) override; + + BooleanEvent* GetTaskEvent(void); }; } diff --git a/source/main.cpp b/source/main.cpp index 214ba3e..28f1f44 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -44,6 +44,11 @@ std::vector NOTIFICATIONS = { "Hmm, Steamed Hams!" }; +nxdt::tasks::GameCardTask *gc_task = nullptr; +nxdt::tasks::TitleTask *title_task = nullptr; +nxdt::tasks::UmsTask *ums_task = nullptr; +nxdt::tasks::UsbHostTask *usb_host_task = nullptr; + int main(int argc, char* argv[]) { ON_SCOPE_EXIT { utilsCloseResources(); }; @@ -60,34 +65,17 @@ int main(int argc, char* argv[]) /* Initialize Borealis. */ if (!brls::Application::init(APP_TITLE)) return EXIT_FAILURE; + /* Start background tasks. */ + gc_task = new nxdt::tasks::GameCardTask(); + title_task = new nxdt::tasks::TitleTask(); + ums_task = new nxdt::tasks::UmsTask(); + usb_host_task = new nxdt::tasks::UsbHostTask(); + /* Create root tab frame. */ brls::TabFrame *root_frame = new brls::TabFrame(); root_frame->setTitle(APP_TITLE); root_frame->setIcon(BOREALIS_ASSET("icon/" APP_TITLE ".jpg")); root_frame->setFooterText("v" APP_VERSION); - - /* Create and start gamecard task. */ - nxdt::tasks::GameCardStatusEvent gc_status_event; - nxdt::tasks::GameCardTask *gc_task = new nxdt::tasks::GameCardTask(&gc_status_event); - gc_task->start(); - - /* Create and start gamecard title task. */ - nxdt::tasks::VoidEvent gc_title_event; - nxdt::tasks::GameCardTitleTask *gc_title_task = new nxdt::tasks::GameCardTitleTask(&gc_title_event); - gc_title_task->start(); - - /* Create and start UMS task. */ - nxdt::tasks::VoidEvent ums_event; - nxdt::tasks::UmsTask *ums_task = new nxdt::tasks::UmsTask(&ums_event); - ums_task->start(); - - /* Create and start USB host task. */ - nxdt::tasks::BooleanEvent usb_host_event; - nxdt::tasks::UsbHostTask *usb_host_task = new nxdt::tasks::UsbHostTask(&usb_host_event); - usb_host_task->start(); - - - diff --git a/source/tasks.cpp b/source/tasks.cpp index fd83bd0..e6d1a8f 100644 --- a/source/tasks.cpp +++ b/source/tasks.cpp @@ -22,15 +22,21 @@ #include #include -#define TASK_INTERVAL 100 /* 100 ms. */ +#define NXDT_TASK_INTERVAL 100 /* 100 ms. */ namespace nxdt::tasks { /* Gamecard task. */ - GameCardTask::GameCardTask(GameCardStatusEvent *gc_status_event) : brls::RepeatingTask(TASK_INTERVAL) + GameCardTask::GameCardTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL) { - this->gc_status_event = gc_status_event; + brls::RepeatingTask::start(); + brls::Logger::debug("Gamecard task started."); + } + + GameCardTask::~GameCardTask(void) + { + brls::Logger::debug("Gamecard task stopped."); } void GameCardTask::run(retro_time_t current_time) @@ -40,35 +46,123 @@ namespace nxdt::tasks this->cur_gc_status = (GameCardStatus)gamecardGetStatus(); if (this->cur_gc_status != this->prev_gc_status) { - this->gc_status_event->fire(this->cur_gc_status); + this->gc_status_event.fire(this->cur_gc_status); this->prev_gc_status = this->cur_gc_status; brls::Logger::debug("Gamecard status change triggered: {}.", this->cur_gc_status); } } - /* Gamecard title task. */ - - GameCardTitleTask::GameCardTitleTask(VoidEvent *gc_title_event) : brls::RepeatingTask(TASK_INTERVAL) + GameCardStatusEvent* GameCardTask::GetTaskEvent(void) { - this->gc_title_event = gc_title_event; + return &(this->gc_status_event); } - void GameCardTitleTask::run(retro_time_t current_time) + /* Title task. */ + + TitleTask::TitleTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL) + { + /* Get system metadata entries. */ + this->PopulateApplicationMetadataVector(true); + + /* Get user metadata entries. */ + this->PopulateApplicationMetadataVector(false); + + /* Start task. */ + brls::RepeatingTask::start(); + brls::Logger::debug("Title task started."); + } + + TitleTask::~TitleTask(void) + { + /* Clear application metadata vectors. */ + this->system_metadata.clear(); + this->user_metadata.clear(); + + brls::Logger::debug("Title task stopped."); + } + + void TitleTask::PopulateApplicationMetadataVector(bool is_system) + { + TitleApplicationMetadata **app_metadata = NULL; + u32 app_metadata_count = 0; + + /* Get pointer to output vector. */ + TitleApplicationMetadataVector *vector = (is_system ? &(this->system_metadata) : &(this->user_metadata)); + if (vector->size()) vector->clear(); + + /* Get application metadata entries. */ + app_metadata = titleGetApplicationMetadataEntries(is_system, &app_metadata_count); + if (!app_metadata) return; + + /* Fill output vector. */ + for(u32 i = 0; i < app_metadata_count; i++) vector->push_back(app_metadata[i]); + + /* Free application metadata array. */ + free(app_metadata); + + brls::Logger::debug("Retrieved {} {} metadata {}.", app_metadata_count, is_system ? "system" : "user", app_metadata_count == 1 ? "entry" : "entries"); + } + + void TitleTask::run(retro_time_t current_time) { brls::RepeatingTask::run(current_time); if (titleIsGameCardInfoUpdated()) { - this->gc_title_event->fire(); - brls::Logger::debug("Gamecard title info updated."); + /* Update user metadata vector. */ + this->PopulateApplicationMetadataVector(false); + + /* Fire task event. */ + this->title_event.fire(); + brls::Logger::debug("Title info updated."); } } + VoidEvent* TitleTask::GetTaskEvent(void) + { + return &(this->title_event); + } + + TitleApplicationMetadataVector* TitleTask::GetApplicationMetadata(bool is_system) + { + return (is_system ? &(this->system_metadata) : &(this->user_metadata)); + } + /* USB Mass Storage task. */ - UmsTask::UmsTask(VoidEvent *ums_event) : brls::RepeatingTask(TASK_INTERVAL) + UmsTask::UmsTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL) { - this->ums_event = ums_event; + brls::RepeatingTask::start(); + brls::Logger::debug("UMS task started."); + } + + UmsTask::~UmsTask(void) + { + /* Clear UMS device vector. */ + this->ums_devices.clear(); + + brls::Logger::debug("UMS task stopped."); + } + + void UmsTask::PopulateUmsDeviceVector(void) + { + UsbHsFsDevice *ums_devices = NULL; + u32 ums_device_count = 0; + + /* Clear UMS device vector (if needed). */ + if (this->ums_devices.size()) this->ums_devices.clear(); + + /* Get UMS devices. */ + ums_devices = umsGetDevices(&ums_device_count); + if (!ums_devices) return; + + /* Fill UMS device vector. */ + for(u32 i = 0; i < ums_device_count; i++) this->ums_devices.push_back(ums_devices[i]); + + /* Free UMS devices array. */ + free(ums_devices); + + brls::Logger::debug("Retrieved info for {} UMS {}.", ums_device_count, ums_device_count == 1 ? "device" : "devices"); } void UmsTask::run(retro_time_t current_time) @@ -77,16 +171,36 @@ namespace nxdt::tasks if (umsIsDeviceInfoUpdated()) { - this->ums_event->fire(); + /* Update UMS device vector. */ + this->PopulateUmsDeviceVector(); + + /* Fire task event. */ + this->ums_event.fire(); brls::Logger::debug("UMS device info updated."); } } + VoidEvent* UmsTask::GetTaskEvent(void) + { + return &(this->ums_event); + } + + UmsDeviceVector* UmsTask::GetUmsDevices(void) + { + return &(this->ums_devices); + } + /* USB host device connection task. */ - UsbHostTask::UsbHostTask(BooleanEvent *usb_host_event) : brls::RepeatingTask(TASK_INTERVAL) + UsbHostTask::UsbHostTask(void) : brls::RepeatingTask(NXDT_TASK_INTERVAL) { - this->usb_host_event = usb_host_event; + brls::RepeatingTask::start(); + brls::Logger::debug("USB host task started."); + } + + UsbHostTask::~UsbHostTask(void) + { + brls::Logger::debug("USB host task stopped."); } void UsbHostTask::run(retro_time_t current_time) @@ -96,9 +210,14 @@ namespace nxdt::tasks this->cur_usb_host_status = usbIsReady(); if (this->cur_usb_host_status != this->prev_usb_host_status) { - this->usb_host_event->fire(this->cur_usb_host_status); + this->usb_host_event.fire(this->cur_usb_host_status); this->prev_usb_host_status = this->cur_usb_host_status; brls::Logger::debug("USB host status change triggered: {}.", this->cur_usb_host_status); } } + + BooleanEvent* UsbHostTask::GetTaskEvent(void) + { + return &(this->usb_host_event); + } }