From c21bfe57c1308cec839ea6f38bd4785e1f60c88d Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Sun, 4 Feb 2007 22:41:44 +0000 Subject: [PATCH] Optimized forwards, now paused functions are stored in a temp list so we dont have to check if they're runnable on each function execution. --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40436 --- core/CPlayerManager.h | 4 +- core/systems/ForwardSys.cpp | 103 +++++++++++++++++++++++++++++++----- core/systems/ForwardSys.h | 26 +++++---- core/systems/PluginSys.cpp | 13 +++++ core/systems/PluginSys.h | 2 + public/IForwardSys.h | 7 ++- public/IPluginSys.h | 7 +++ 7 files changed, 131 insertions(+), 31 deletions(-) diff --git a/core/CPlayerManager.h b/core/CPlayerManager.h index 98060a8e..c2dc1dd7 100644 --- a/core/CPlayerManager.h +++ b/core/CPlayerManager.h @@ -27,8 +27,8 @@ class CPlayerManager : public SMGlobalClass public: CPlayerManager() : m_FirstPass(true) {} public: //SMGlobalClass - virtual void OnSourceModAllInitialized(); - virtual void OnSourceModShutdown(); + void OnSourceModAllInitialized(); + void OnSourceModShutdown(); public: int GetMaxClients() const; CPlayer *GetPlayerByIndex(int client) const; diff --git a/core/systems/ForwardSys.cpp b/core/systems/ForwardSys.cpp index d627e5e3..95fd06c6 100644 --- a/core/systems/ForwardSys.cpp +++ b/core/systems/ForwardSys.cpp @@ -177,6 +177,37 @@ CForward *CForwardManager::ForwardMake() return fwd; } +void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused) +{ + List::iterator iter; + CForward *fwd; + + if (paused) + { + for (iter=m_managed.begin(); iter!=m_managed.end(); iter++) + { + fwd = (*iter); + fwd->PushPausedFunctions(plugin); + } + for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++) + { + fwd = (*iter); + fwd->PushPausedFunctions(plugin); + } + } else { + for (iter=m_managed.begin(); iter!=m_managed.end(); iter++) + { + fwd = (*iter); + fwd->PopPausedFunctions(plugin); + } + for (iter=m_unmanaged.begin(); iter!=m_unmanaged.end(); iter++) + { + fwd = (*iter); + fwd->PopPausedFunctions(plugin); + } + } +} + /************************************* * ACTUAL FORWARD API IMPLEMENTATION * *************************************/ @@ -272,11 +303,6 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter) for (iter=m_functions.begin(); iter!=m_functions.end(); iter++) { func = (*iter); - /* Ugh... */ - if (!func->GetParentContext()->IsRunnable()) - { - continue; - } for (unsigned int i=0; i *lst; - for (iter=m_functions.begin(); iter!=m_functions.end();) + if (func->GetParentContext()->IsRunnable()) + { + lst = &m_functions; + } else { + lst = &m_paused; + } + + for (iter=lst->begin(); iter!=lst->end(); iter++) { if ((*iter) == func) { found = true; - /* If this iterator is being used, swap in a new one !*/ - iter = m_functions.erase(iter); - } else { - iter++; + lst->erase(iter); + break; } } @@ -653,22 +685,65 @@ bool CForward::AddFunction(IPluginFunction *func) } //:IDEA: eventually we will tell the plugin we're using it [?] - m_functions.push_back(func); + if (func->GetParentContext()->IsRunnable()) + { + m_functions.push_back(func); + } else { + m_paused.push_back(func); + } return true; } -const char *CForward::GetForwardName() +const char *CForward::GetForwardName() const { return m_name; } -unsigned int CForward::GetFunctionCount() +unsigned int CForward::GetFunctionCount() const { return m_functions.size(); } -ExecType CForward::GetExecType() +ExecType CForward::GetExecType() const { return m_ExecType; } + +void CForward::PushPausedFunctions(IPlugin *plugin) +{ + FuncIter iter; + IPluginFunction *func; + IPluginContext *pContext = plugin->GetBaseContext(); + + for (iter=m_functions.begin(); iter!=m_functions.end();) + { + func = (*iter); + if (func->GetParentContext() == pContext) + { + m_paused.push_back(func); + iter = m_functions.erase(iter); + } else { + iter++; + } + } +} + +void CForward::PopPausedFunctions(IPlugin *plugin) +{ + FuncIter iter; + IPluginFunction *func; + IPluginContext *pContext = plugin->GetBaseContext(); + + for (iter=m_paused.begin(); iter!=m_paused.end();) + { + func = (*iter); + if (func->GetParentContext() == pContext) + { + m_functions.push_back(func); + iter = m_paused.erase(iter); + } else { + iter++; + } + } +} diff --git a/core/systems/ForwardSys.h b/core/systems/ForwardSys.h index 73e58663..e8e16ae7 100644 --- a/core/systems/ForwardSys.h +++ b/core/systems/ForwardSys.h @@ -55,9 +55,9 @@ public: //ICallable virtual int PushStringEx(char *buffer, size_t length, int sz_flags, int cp_flags); virtual void Cancel(); public: //IForward - virtual const char *GetForwardName(); - virtual unsigned int GetFunctionCount(); - virtual ExecType GetExecType(); + virtual const char *GetForwardName() const; + virtual unsigned int GetFunctionCount() const; + virtual ExecType GetExecType() const; virtual int Execute(cell_t *result, IForwardFilter *filter); public: //IChangeableForward virtual bool RemoveFunction(IPluginFunction *func); @@ -70,6 +70,8 @@ public: unsigned int num_params, ParamType *types, va_list ap); + void PushPausedFunctions(IPlugin *plugin); + void PopPausedFunctions(IPlugin *plugin); private: void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags); void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags); @@ -83,6 +85,7 @@ protected: * Destroying these things and using new/delete for their members feels bad. */ List m_functions; + List m_paused; /* Type and name information */ FwdParamInfo m_params[SP_MAX_EXEC_PARAMS]; @@ -104,24 +107,25 @@ class CForwardManager : { friend class CForward; public: //IForwardManager - virtual IForward *CreateForward(const char *name, + IForward *CreateForward(const char *name, ExecType et, unsigned int num_params, ParamType *types, ...); - virtual IChangeableForward *CreateForwardEx(const char *name, + IChangeableForward *CreateForwardEx(const char *name, ExecType et, int num_params, ParamType *types, ...); - virtual IForward *FindForward(const char *name, IChangeableForward **ifchng); - virtual void ReleaseForward(IForward *forward); + IForward *FindForward(const char *name, IChangeableForward **ifchng); + void ReleaseForward(IForward *forward); public: //IPluginsListener - virtual void OnPluginLoaded(IPlugin *plugin); - virtual void OnPluginUnloaded(IPlugin *plugin); + void OnPluginLoaded(IPlugin *plugin); + void OnPluginUnloaded(IPlugin *plugin); + void OnPluginPauseChange(IPlugin *plugin, bool paused); public: //SMGlobalClass - virtual void OnSourceModAllInitialized(); - virtual void OnSourceModShutdown(); + void OnSourceModAllInitialized(); + void OnSourceModShutdown(); protected: CForward *ForwardMake(); void ForwardFree(CForward *fwd); diff --git a/core/systems/PluginSys.cpp b/core/systems/PluginSys.cpp index 6eb5941e..95cded30 100644 --- a/core/systems/PluginSys.cpp +++ b/core/systems/PluginSys.cpp @@ -385,6 +385,8 @@ bool CPlugin::SetPauseState(bool paused) pFunction->Execute(&result); } + g_PluginSys._SetPauseState(this, paused); + return true; } @@ -1636,3 +1638,14 @@ void CPluginManager::ReloadOrUnloadPlugins() } } } + +void CPluginManager::_SetPauseState(CPlugin *pl, bool paused) +{ + List::iterator iter; + IPluginsListener *pListener; + for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++) + { + pListener = (*iter); + pListener->OnPluginPauseChange(pl, paused); + } +} \ No newline at end of file diff --git a/core/systems/PluginSys.h b/core/systems/PluginSys.h index b46bd356..4954fe40 100644 --- a/core/systems/PluginSys.h +++ b/core/systems/PluginSys.h @@ -355,6 +355,8 @@ private: * Runs an extension pass on a plugin. */ bool LoadOrRequireExtensions(CPlugin *pPlugin, unsigned int pass, char *error, size_t maxlength); + + void _SetPauseState(CPlugin *pPlugin, bool pause); protected: /** * Caching internal objects diff --git a/public/IForwardSys.h b/public/IForwardSys.h index 6d467e1d..9139ef02 100644 --- a/public/IForwardSys.h +++ b/public/IForwardSys.h @@ -31,7 +31,6 @@ * function name in all plugins. */ -#include #include #include @@ -147,21 +146,21 @@ namespace SourceMod * * @return Forward name. */ - virtual const char *GetForwardName() =0; + virtual const char *GetForwardName() const =0; /** * @brief Returns the number of functions in this forward. * * @return Number of functions in forward. */ - virtual unsigned int GetFunctionCount() =0; + virtual unsigned int GetFunctionCount() const =0; /** * @brief Returns the method of multi-calling this forward has. * * @return ExecType of the forward. */ - virtual ExecType GetExecType() =0; + virtual ExecType GetExecType() const =0; /** * @brief Executes the forward. diff --git a/public/IPluginSys.h b/public/IPluginSys.h index 1feb5858..45e9a78d 100644 --- a/public/IPluginSys.h +++ b/public/IPluginSys.h @@ -210,6 +210,13 @@ namespace SourceMod { } + /** + * @brief Called when a plugin is paused or unpaused. + */ + virtual void OnPluginPauseChange(IPlugin *plugin, bool paused) + { + } + /** * @brief Called when a plugin is unloaded (only if fully loaded). */