From 209051a24b5deb47dcbc39db898cb6ad8be34016 Mon Sep 17 00:00:00 2001 From: Angad <66992519+ThirdEyeSqueegee@users.noreply.github.com> Date: Mon, 23 Oct 2023 19:32:27 -0700 Subject: [PATCH] feat: add `TaskInterface` (#191) --- CommonLibSF/include/SFSE/API.h | 2 ++ CommonLibSF/include/SFSE/Impl/Stubs.h | 14 +++++++++ CommonLibSF/include/SFSE/Interfaces.h | 37 ++++++++++++++++++++++ CommonLibSF/src/SFSE/API.cpp | 7 +++++ CommonLibSF/src/SFSE/Interfaces.cpp | 45 +++++++++++++++++++++++++++ 5 files changed, 105 insertions(+) diff --git a/CommonLibSF/include/SFSE/API.h b/CommonLibSF/include/SFSE/API.h index ad7b951f..f80f93d5 100644 --- a/CommonLibSF/include/SFSE/API.h +++ b/CommonLibSF/include/SFSE/API.h @@ -20,6 +20,8 @@ namespace SFSE const MenuInterface* GetMenuInterface() noexcept; + const TaskInterface* GetTaskInterface() noexcept; + Trampoline& GetTrampoline(); void AllocTrampoline(std::size_t a_size, bool a_trySFSEReserve = true); diff --git a/CommonLibSF/include/SFSE/Impl/Stubs.h b/CommonLibSF/include/SFSE/Impl/Stubs.h index eff493c9..fb7137de 100644 --- a/CommonLibSF/include/SFSE/Impl/Stubs.h +++ b/CommonLibSF/include/SFSE/Impl/Stubs.h @@ -47,5 +47,19 @@ namespace SFSE std::uint32_t interfaceVersion; void (*Register)(void*); }; + + struct SFSETaskInterface + { + std::uint32_t interfaceVersion; + void (*AddTask)(void*); + void (*AddPermanentTask)(void*); + }; } + + class ITaskDelegate + { + public: + virtual void Run() = 0; + virtual void Destroy() = 0; + }; } diff --git a/CommonLibSF/include/SFSE/Interfaces.h b/CommonLibSF/include/SFSE/Interfaces.h index c7db8052..a88aaf06 100644 --- a/CommonLibSF/include/SFSE/Interfaces.h +++ b/CommonLibSF/include/SFSE/Interfaces.h @@ -31,6 +31,7 @@ namespace SFSE kMessaging, kTrampoline, kMenu, + kTask, kTotal }; @@ -116,6 +117,42 @@ namespace SFSE [[nodiscard]] const detail::SFSEMenuInterface* GetProxy() const; }; + class TaskInterface + { + public: + using TaskFn = std::function; + + enum Version : std::uint32_t + { + kVersion = 1 + }; + + [[nodiscard]] std::uint32_t Version() const; + + void AddTask(TaskFn a_fn) const; + + void AddTask(ITaskDelegate* a_task) const; + + void AddPermanentTask(TaskFn a_fn) const; + + void AddPermanentTask(ITaskDelegate* a_task) const; + + private: + class Task : public ITaskDelegate + { + public: + Task(TaskFn&& a_fn); + + void Run() override; + void Destroy() override; + + private: + TaskFn _fn; + }; + + [[nodiscard]] const detail::SFSETaskInterface* GetProxy() const; + }; + struct PluginInfo { enum Version : std::uint32_t diff --git a/CommonLibSF/src/SFSE/API.cpp b/CommonLibSF/src/SFSE/API.cpp index aef29ee7..e78079af 100644 --- a/CommonLibSF/src/SFSE/API.cpp +++ b/CommonLibSF/src/SFSE/API.cpp @@ -20,6 +20,7 @@ namespace SFSE TrampolineInterface* trampolineInterface{}; MessagingInterface* messagingInterface{}; MenuInterface* menuInterface{}; + TaskInterface* taskInterface{}; std::mutex apiLock; std::vector> apiInitRegs; @@ -69,6 +70,7 @@ namespace SFSE storage.messagingInterface = detail::QueryInterface(a_intfc, LoadInterface::kMessaging); storage.trampolineInterface = detail::QueryInterface(a_intfc, LoadInterface::kTrampoline); storage.menuInterface = detail::QueryInterface(a_intfc, LoadInterface::kMenu); + storage.taskInterface = detail::QueryInterface(a_intfc, LoadInterface::kTask); storage.apiInit = true; auto& regs = storage.apiInitRegs; @@ -114,6 +116,11 @@ namespace SFSE return detail::APIStorage::get().menuInterface; } + const TaskInterface* GetTaskInterface() noexcept + { + return detail::APIStorage::get().taskInterface; + } + Trampoline& GetTrampoline() { static Trampoline trampoline; diff --git a/CommonLibSF/src/SFSE/Interfaces.cpp b/CommonLibSF/src/SFSE/Interfaces.cpp index 79c71555..8d4f396f 100644 --- a/CommonLibSF/src/SFSE/Interfaces.cpp +++ b/CommonLibSF/src/SFSE/Interfaces.cpp @@ -113,6 +113,51 @@ namespace SFSE return reinterpret_cast(this); } + std::uint32_t TaskInterface::Version() const + { + return GetProxy()->interfaceVersion; + } + + void TaskInterface::AddTask(TaskFn a_fn) const + { + return GetProxy()->AddTask(new Task(std::move(a_fn))); + } + + void TaskInterface::AddTask(ITaskDelegate* a_task) const + { + return GetProxy()->AddTask(a_task); + } + + void TaskInterface::AddPermanentTask(TaskFn a_fn) const + { + return GetProxy()->AddPermanentTask(new Task(std::move(a_fn))); + } + + void TaskInterface::AddPermanentTask(ITaskDelegate* a_task) const + { + return GetProxy()->AddPermanentTask(a_task); + } + + TaskInterface::Task::Task(TaskFn&& a_fn) : + _fn(std::move(a_fn)) + {} + + void TaskInterface::Task::Run() + { + _fn(); + } + + void TaskInterface::Task::Destroy() + { + delete this; + } + + const detail::SFSETaskInterface* TaskInterface::GetProxy() const + { + assert(this); + return reinterpret_cast(this); + } + const PluginVersionData* PluginVersionData::GetSingleton() noexcept { return reinterpret_cast(WinAPI::GetProcAddress(WinAPI::GetCurrentModule(), "SFSEPlugin_Version"));