From b13c542ed160a03c1f7b536687c15df6e3b551c3 Mon Sep 17 00:00:00 2001 From: Marvin D <41352111+IcePixelx@users.noreply.github.com> Date: Mon, 12 Dec 2022 17:16:39 +0100 Subject: [PATCH] CPluginCallbackList impl * CPluginSystem allows for function callbacks now. --- r5dev/launcher/IApplication.cpp | 24 +++++--- r5dev/launcher/IApplication.h | 1 + r5dev/pluginsystem/pluginsystem.cpp | 48 +++++++++++++-- r5dev/pluginsystem/pluginsystem.h | 90 ++++++++++++++++++++++++++++- 4 files changed, 148 insertions(+), 15 deletions(-) diff --git a/r5dev/launcher/IApplication.cpp b/r5dev/launcher/IApplication.cpp index 672bbd54..c4cf6452 100644 --- a/r5dev/launcher/IApplication.cpp +++ b/r5dev/launcher/IApplication.cpp @@ -64,14 +64,9 @@ bool CModAppSystemGroup::Create(CModAppSystemGroup* pModAppSystemGroup) g_pFactory->GetFactoriesFromRegister(); g_pFactory->AddFactory(FACTORY_INTERFACE_VERSION, g_pFactory); g_pFactory->AddFactory(INTERFACEVERSION_PLUGINSYSTEM, g_pPluginSystem); - - // DEBUG CODE FOR PLUGINS - //g_pPluginSystem->PluginSystem_Init(); - //for (auto& it : g_pPluginSystem->GetPluginInstances()) - //{ - // if (g_pPluginSystem->LoadPluginInstance(it)) - // spdlog::info("Load PLUGIN SUCCESS\n"); - //} + + //InitPluginSystem(pModAppSystemGroup); + //CALL_PLUGIN_CALLBACKS(g_pPluginSystem->GetCreateCallbacks(), pModAppSystemGroup); #ifndef DEDICATED g_pClientEntityList = g_pFactory->GetFactoryPtr("VClientEntityList003", false).RCast(); @@ -99,6 +94,19 @@ bool CModAppSystemGroup::Create(CModAppSystemGroup* pModAppSystemGroup) return CModAppSystemGroup_Create(pModAppSystemGroup); } +//----------------------------------------------------------------------------- +// Purpose: Initialize plugin system +//----------------------------------------------------------------------------- +void CModAppSystemGroup::InitPluginSystem(CModAppSystemGroup* pModAppSystemGroup) +{ + // DEBUG CODE FOR PLUGINS + g_pPluginSystem->PluginSystem_Init(); + for (auto& it : g_pPluginSystem->GetPluginInstances()) + { + if (g_pPluginSystem->LoadPluginInstance(it)) + spdlog::info("Load PLUGIN SUCCESS\n"); + } +} /////////////////////////////////////////////////////////////////////////////// void IApplication_Attach() diff --git a/r5dev/launcher/IApplication.h b/r5dev/launcher/IApplication.h index bc3d5c06..9d1f839a 100644 --- a/r5dev/launcher/IApplication.h +++ b/r5dev/launcher/IApplication.h @@ -9,6 +9,7 @@ class CModAppSystemGroup public: static int Main(CModAppSystemGroup* pModAppSystemGroup); static bool Create(CModAppSystemGroup* pModAppSystemGroup); + static void InitPluginSystem(CModAppSystemGroup* pModAppSystemGroup); bool IsServerOnly(void) const { diff --git a/r5dev/pluginsystem/pluginsystem.cpp b/r5dev/pluginsystem/pluginsystem.cpp index 94a015e3..19232bd7 100644 --- a/r5dev/pluginsystem/pluginsystem.cpp +++ b/r5dev/pluginsystem/pluginsystem.cpp @@ -112,13 +112,49 @@ vector& CPluginSystem::GetPluginInstances() } //----------------------------------------------------------------------------- -// Purpose: get all plugin callbacks -// Input : -// Output : unordered_map>>& +// Purpose: add plugin callback for function +// Input : *help +// Output : void //----------------------------------------------------------------------------- -unordered_map>>& CPluginSystem::GetPluginCallbacks() +void CPluginSystem::AddPluginCallback(PluginHelpWithAnything_t* help) { - return pluginCallbacks; +#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast(function) + + switch (help->m_nCallbackID) + { + case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create: + { + ADD_PLUGIN_CALLBACK(CreateFn, GetCreateCallbacks(), help->m_pFunction); + break; + } + default: + break; + } + +#undef ADD_PLUGIN_CALLBACK +} + +//----------------------------------------------------------------------------- +// Purpose: remove plugin callback for function +// Input : *help +// Output : void +//----------------------------------------------------------------------------- +void CPluginSystem::RemovePluginCallback(PluginHelpWithAnything_t* help) +{ +#define REMOVE_PLUGIN_CALLBACK(fn, callback, function) callback -= reinterpret_cast(function) + + switch (help->m_nCallbackID) + { + case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create: + { + REMOVE_PLUGIN_CALLBACK(CreateFn, GetCreateCallbacks(), help->m_pFunction); + break; + } + default: + break; + } + +#undef REMOVE_PLUGIN_CALLBACK } //----------------------------------------------------------------------------- @@ -136,10 +172,12 @@ void* CPluginSystem::HelpWithAnything(PluginHelpWithAnything_t* help) } case PluginHelpWithAnything_t::ePluginHelp::PLUGIN_REGISTER_CALLBACK: { + AddPluginCallback(help); break; } case PluginHelpWithAnything_t::ePluginHelp::PLUGIN_UNREGISTER_CALLBACK: { + RemovePluginCallback(help); break; } default: diff --git a/r5dev/pluginsystem/pluginsystem.h b/r5dev/pluginsystem/pluginsystem.h index ced1c047..83883f69 100644 --- a/r5dev/pluginsystem/pluginsystem.h +++ b/r5dev/pluginsystem/pluginsystem.h @@ -1,6 +1,8 @@ #pragma once #include "ipluginsystem.h" +class CModAppSystemGroup; + struct PluginHelpWithAnything_t { enum class ePluginHelp : int16_t @@ -10,11 +12,84 @@ struct PluginHelpWithAnything_t PLUGIN_UNREGISTER_CALLBACK }; + enum ePluginCallback : int16_t + { + CModAppSystemGroup_Create = 0 + }; + ePluginHelp m_nHelpID; + ePluginCallback m_nCallbackID; const char* m_pszName; void* m_pFunction; }; +template +class CPluginCallbackList +{ +public: + CPluginCallbackList() : m_vCallbacks() {} + CPluginCallbackList(const vector& cbs) : m_vCallbacks(cbs) {} + + vector& GetCallbacks() { return m_vCallbacks; } + + operator bool() + { + return !this->m_vCallbacks.empty; + } + + vector& operator!() + { + return this->m_vCallbacks; + } + + CPluginCallbackList& operator+=(const T& rhs) + { + if (rhs) + this->m_vCallbacks.push_back(rhs); + + return *this; + } + + CPluginCallbackList& operator+=(const vector& rhs) + { + for (auto it : rhs) + { + if (it) + this->m_vCallbacks.push_back(it); + } + + return *this; + } + + CPluginCallbackList& operator-=(const T& rhs) + { + if (rhs) { + auto it = std::find(m_vCallbacks.begin(), m_vCallbacks.end(), rhs); + if (it != m_vCallbacks.end()) + m_vCallbacks.erase(it); + } + + return *this; + } + + CPluginCallbackList& operator-=(const vector& rhs) + { + for (auto itc : rhs) + { + if (itc) { + auto it = std::find(m_vCallbacks.begin(), m_vCallbacks.end(), itc); + if (it != m_vCallbacks.end()) + m_vCallbacks.erase(it); + } + } + + return *this; + } + +private: + vector m_vCallbacks; +}; + class CPluginSystem : IPluginSystem { public: @@ -38,14 +113,25 @@ public: bool ReloadPluginInstance(PluginInstance_t& pluginInst); bool LoadPluginInstance(PluginInstance_t& pluginInst); bool UnloadPluginInstance(PluginInstance_t& pluginInst); + void AddPluginCallback(PluginHelpWithAnything_t* help); + void RemovePluginCallback(PluginHelpWithAnything_t* help); vector& GetPluginInstances(); - unordered_map>>& GetPluginCallbacks(); virtual void* HelpWithAnything(PluginHelpWithAnything_t* help); +#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList& funcName() { return varName; } private: CPluginCallbackList varName; + + CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks); + +#undef CREATE_PLUGIN_CALLBACK + private: vector pluginInstances; - unordered_map>> pluginCallbacks; }; extern CPluginSystem* g_pPluginSystem; + +// Monitor this and performance profile this if fps drops are detected. +#define CALL_PLUGIN_CALLBACKS(callback, ...) \ + for (auto& cb : !callback) \ + cb(__VA_ARGS__) \ No newline at end of file