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
This commit is contained in:
Borja Ferrer 2007-02-04 22:41:44 +00:00
parent 4f5edf7b1f
commit c21bfe57c1
7 changed files with 131 additions and 31 deletions

View File

@ -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;

View File

@ -177,6 +177,37 @@ CForward *CForwardManager::ForwardMake()
return fwd;
}
void CForwardManager::OnPluginPauseChange(IPlugin *plugin, bool paused)
{
List<CForward *>::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<num_params; i++)
{
@ -602,16 +628,22 @@ bool CForward::RemoveFunction(IPluginFunction *func)
{
bool found = false;
FuncIter iter;
List<IPluginFunction *> *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++;
}
}
}

View File

@ -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<IPluginFunction *> m_functions;
List<IPluginFunction *> 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);

View File

@ -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<IPluginsListener *>::iterator iter;
IPluginsListener *pListener;
for (iter=m_listeners.begin(); iter!=m_listeners.end(); iter++)
{
pListener = (*iter);
pListener->OnPluginPauseChange(pl, paused);
}
}

View File

@ -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

View File

@ -31,7 +31,6 @@
* function name in all plugins.
*/
#include <IForwardSys.h>
#include <IPluginSys.h>
#include <sp_vm_api.h>
@ -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.

View File

@ -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).
*/