Corrected an API design flaw with pausing. Contexts can now be flagged as paused, and IsRunnable() is moved from IBaseContext to IPluginFunction. While this allows for per-function pausing, it is not intended that way.
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40531
This commit is contained in:
parent
3de592d387
commit
8553f12d59
@ -151,6 +151,10 @@ ResultType CConCmdManager::DispatchClientCommand(int client, ResultType type)
|
|||||||
iter++)
|
iter++)
|
||||||
{
|
{
|
||||||
pHook = (*iter);
|
pHook = (*iter);
|
||||||
|
if (!pHook->pf->IsRunnable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
|
if (pHook->pAdmin && !CheckAccess(client, cmd, pHook->pAdmin))
|
||||||
{
|
{
|
||||||
if (result < Pl_Handled)
|
if (result < Pl_Handled)
|
||||||
@ -210,6 +214,10 @@ void CConCmdManager::InternalDispatch()
|
|||||||
iter++)
|
iter++)
|
||||||
{
|
{
|
||||||
pHook = (*iter);
|
pHook = (*iter);
|
||||||
|
if (!pHook->pf->IsRunnable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
pHook->pf->PushCell(args);
|
pHook->pf->PushCell(args);
|
||||||
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
if (pHook->pf->Execute(&tempres) == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
@ -244,6 +252,10 @@ void CConCmdManager::InternalDispatch()
|
|||||||
iter++)
|
iter++)
|
||||||
{
|
{
|
||||||
pHook = (*iter);
|
pHook = (*iter);
|
||||||
|
if (!pHook->pf->IsRunnable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (m_CmdClient
|
if (m_CmdClient
|
||||||
&& pHook->pAdmin
|
&& pHook->pAdmin
|
||||||
&& !CheckAccess(m_CmdClient, cmd, pHook->pAdmin))
|
&& !CheckAccess(m_CmdClient, cmd, pHook->pAdmin))
|
||||||
|
@ -304,6 +304,11 @@ int CForward::Execute(cell_t *result, IForwardFilter *filter)
|
|||||||
{
|
{
|
||||||
func = (*iter);
|
func = (*iter);
|
||||||
|
|
||||||
|
if (!func->IsRunnable())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i=0; i<num_params; i++)
|
for (unsigned int i=0; i<num_params; i++)
|
||||||
{
|
{
|
||||||
param = &temp_info[i];
|
param = &temp_info[i];
|
||||||
@ -633,21 +638,13 @@ bool CForward::RemoveFunction(IPluginFunction *func)
|
|||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
FuncIter iter;
|
FuncIter iter;
|
||||||
List<IPluginFunction *> *lst;
|
|
||||||
|
|
||||||
if (func->GetParentContext()->IsRunnable())
|
for (iter=m_functions.begin(); iter!=m_functions.end(); iter++)
|
||||||
{
|
|
||||||
lst = &m_functions;
|
|
||||||
} else {
|
|
||||||
lst = &m_paused;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (iter=lst->begin(); iter!=lst->end(); iter++)
|
|
||||||
{
|
{
|
||||||
if ((*iter) == func)
|
if ((*iter) == func)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
lst->erase(iter);
|
m_functions.erase(iter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,13 +686,7 @@ bool CForward::AddFunction(IPluginFunction *func)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//:IDEA: eventually we will tell the plugin we're using it [?]
|
|
||||||
if (func->GetParentContext()->IsRunnable())
|
|
||||||
{
|
|
||||||
m_functions.push_back(func);
|
m_functions.push_back(func);
|
||||||
} else {
|
|
||||||
m_paused.push_back(func);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,6 @@ bool CPlugin::FinishMyCompile(char *error, size_t maxlength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_ctx.base = new BaseContext(m_ctx.ctx);
|
m_ctx.base = new BaseContext(m_ctx.ctx);
|
||||||
m_ctx.base->SetRunnable(false);
|
|
||||||
m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
|
m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
|
||||||
|
|
||||||
m_status = Plugin_Created;
|
m_status = Plugin_Created;
|
||||||
@ -222,9 +221,9 @@ void CPlugin::SetErrorState(PluginStatus status, const char *error_fmt, ...)
|
|||||||
vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
|
vsnprintf(m_errormsg, sizeof(m_errormsg), error_fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
if (m_ctx.base)
|
if (m_ctx.ctx)
|
||||||
{
|
{
|
||||||
m_ctx.base->SetRunnable(false);
|
m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +309,6 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_status = Plugin_Loaded;
|
m_status = Plugin_Loaded;
|
||||||
m_ctx.base->SetRunnable(true);
|
|
||||||
|
|
||||||
int err;
|
int err;
|
||||||
cell_t result;
|
cell_t result;
|
||||||
@ -397,8 +395,6 @@ bool CPlugin::SetPauseState(bool paused)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_status = (paused) ? Plugin_Paused : Plugin_Running;
|
|
||||||
|
|
||||||
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange");
|
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange");
|
||||||
if (pFunction)
|
if (pFunction)
|
||||||
{
|
{
|
||||||
@ -407,6 +403,15 @@ bool CPlugin::SetPauseState(bool paused)
|
|||||||
pFunction->Execute(&result);
|
pFunction->Execute(&result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (paused)
|
||||||
|
{
|
||||||
|
m_status = Plugin_Paused;
|
||||||
|
m_ctx.ctx->flags |= SPFLAG_PLUGIN_PAUSED;
|
||||||
|
} else {
|
||||||
|
m_status = Plugin_Running;
|
||||||
|
m_ctx.ctx->flags &= ~SPFLAG_PLUGIN_PAUSED;
|
||||||
|
}
|
||||||
|
|
||||||
g_PluginSys._SetPauseState(this, paused);
|
g_PluginSys._SetPauseState(this, paused);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -40,7 +40,6 @@ BaseContext::BaseContext(sp_context_t *_ctx)
|
|||||||
ctx->dbreak = GlobalDebugBreak;
|
ctx->dbreak = GlobalDebugBreak;
|
||||||
m_InExec = false;
|
m_InExec = false;
|
||||||
m_CustomMsg = false;
|
m_CustomMsg = false;
|
||||||
m_Runnable = true;
|
|
||||||
m_funcsnum = ctx->vmbase->FunctionCount(ctx);
|
m_funcsnum = ctx->vmbase->FunctionCount(ctx);
|
||||||
m_priv_funcs = NULL;
|
m_priv_funcs = NULL;
|
||||||
m_pub_funcs = NULL;
|
m_pub_funcs = NULL;
|
||||||
@ -153,7 +152,7 @@ IPluginDebugInfo *BaseContext::GetDebugInfo()
|
|||||||
|
|
||||||
int BaseContext::Execute(uint32_t code_addr, cell_t *result)
|
int BaseContext::Execute(uint32_t code_addr, cell_t *result)
|
||||||
{
|
{
|
||||||
if (!m_Runnable)
|
if ((ctx->flags & SPFLAG_PLUGIN_PAUSED) == SPFLAG_PLUGIN_PAUSED)
|
||||||
{
|
{
|
||||||
return SP_ERROR_NOT_RUNNABLE;
|
return SP_ERROR_NOT_RUNNABLE;
|
||||||
}
|
}
|
||||||
@ -928,14 +927,4 @@ void BaseContext::SetIdentity(SourceMod::IdentityToken_t *token)
|
|||||||
{
|
{
|
||||||
m_pToken = token;
|
m_pToken = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseContext::IsRunnable()
|
|
||||||
{
|
|
||||||
return m_Runnable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseContext::SetRunnable(bool runnable)
|
|
||||||
{
|
|
||||||
m_Runnable = runnable;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -68,8 +68,6 @@ namespace SourcePawn
|
|||||||
#if defined SOURCEMOD_BUILD
|
#if defined SOURCEMOD_BUILD
|
||||||
virtual SourceMod::IdentityToken_t *GetIdentity();
|
virtual SourceMod::IdentityToken_t *GetIdentity();
|
||||||
void SetIdentity(SourceMod::IdentityToken_t *token);
|
void SetIdentity(SourceMod::IdentityToken_t *token);
|
||||||
bool IsRunnable();
|
|
||||||
void SetRunnable(bool runnable);
|
|
||||||
#endif
|
#endif
|
||||||
public: //IPluginDebugInfo
|
public: //IPluginDebugInfo
|
||||||
virtual int LookupFile(ucell_t addr, const char **filename);
|
virtual int LookupFile(ucell_t addr, const char **filename);
|
||||||
@ -88,7 +86,6 @@ namespace SourcePawn
|
|||||||
char m_MsgCache[1024];
|
char m_MsgCache[1024];
|
||||||
bool m_CustomMsg;
|
bool m_CustomMsg;
|
||||||
bool m_InExec;
|
bool m_InExec;
|
||||||
bool m_Runnable;
|
|
||||||
unsigned int m_funcsnum;
|
unsigned int m_funcsnum;
|
||||||
CFunction **m_priv_funcs;
|
CFunction **m_priv_funcs;
|
||||||
CFunction **m_pub_funcs;
|
CFunction **m_pub_funcs;
|
||||||
|
@ -26,10 +26,21 @@ void CFunction::Set(uint32_t code_addr, IPluginContext *plugin)
|
|||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
m_Invalid = false;
|
m_Invalid = false;
|
||||||
|
m_pCtx = plugin ? plugin->GetContext() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFunction::IsRunnable()
|
||||||
|
{
|
||||||
|
return ((m_pCtx->flags & SPFLAG_PLUGIN_PAUSED) != SPFLAG_PLUGIN_PAUSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
|
int CFunction::CallFunction(const cell_t *params, unsigned int num_params, cell_t *result)
|
||||||
{
|
{
|
||||||
|
if (!IsRunnable())
|
||||||
|
{
|
||||||
|
return SP_ERROR_NOT_RUNNABLE;
|
||||||
|
}
|
||||||
|
|
||||||
while (num_params--)
|
while (num_params--)
|
||||||
{
|
{
|
||||||
m_pContext->PushCell(params[num_params]);
|
m_pContext->PushCell(params[num_params]);
|
||||||
@ -48,6 +59,10 @@ CFunction::CFunction(uint32_t code_addr, IPluginContext *plugin) :
|
|||||||
m_errorstate(SP_ERROR_NONE)
|
m_errorstate(SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
m_Invalid = false;
|
m_Invalid = false;
|
||||||
|
if (plugin)
|
||||||
|
{
|
||||||
|
m_pCtx = plugin->GetContext();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CFunction::PushCell(cell_t cell)
|
int CFunction::PushCell(cell_t cell)
|
||||||
@ -201,6 +216,10 @@ void CFunction::Cancel()
|
|||||||
int CFunction::Execute(cell_t *result)
|
int CFunction::Execute(cell_t *result)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
if (!IsRunnable())
|
||||||
|
{
|
||||||
|
m_errorstate = SP_ERROR_NOT_RUNNABLE;
|
||||||
|
}
|
||||||
if (m_errorstate != SP_ERROR_NONE)
|
if (m_errorstate != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
err = m_errorstate;
|
err = m_errorstate;
|
||||||
|
@ -54,6 +54,7 @@ public:
|
|||||||
{
|
{
|
||||||
m_Invalid = true;
|
m_Invalid = true;
|
||||||
}
|
}
|
||||||
|
bool IsRunnable();
|
||||||
public:
|
public:
|
||||||
void Set(uint32_t code_addr, IPluginContext *plugin);
|
void Set(uint32_t code_addr, IPluginContext *plugin);
|
||||||
private:
|
private:
|
||||||
@ -66,6 +67,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
uint32_t m_codeaddr;
|
uint32_t m_codeaddr;
|
||||||
IPluginContext *m_pContext;
|
IPluginContext *m_pContext;
|
||||||
|
sp_context_t *m_pCtx;
|
||||||
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
cell_t m_params[SP_MAX_EXEC_PARAMS];
|
||||||
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
ParamInfo m_info[SP_MAX_EXEC_PARAMS];
|
||||||
unsigned int m_curparam;
|
unsigned int m_curparam;
|
||||||
|
@ -184,6 +184,13 @@ namespace SourcePawn
|
|||||||
* @return Address, or NULL if invalid parameter specified.
|
* @return Address, or NULL if invalid parameter specified.
|
||||||
*/
|
*/
|
||||||
virtual cell_t *GetAddressOfPushedParam(unsigned int param) =0;
|
virtual cell_t *GetAddressOfPushedParam(unsigned int param) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns whether the parent plugin is paused.
|
||||||
|
*
|
||||||
|
* @return True if runnable, false otherwise.
|
||||||
|
*/
|
||||||
|
virtual bool IsRunnable() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -534,13 +541,6 @@ namespace SourcePawn
|
|||||||
* @return Identity token.
|
* @return Identity token.
|
||||||
*/
|
*/
|
||||||
virtual SourceMod::IdentityToken_t *GetIdentity() =0;
|
virtual SourceMod::IdentityToken_t *GetIdentity() =0;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns whether the identity is runnable.
|
|
||||||
*
|
|
||||||
* @return True if runnable, false otherwise.
|
|
||||||
*/
|
|
||||||
virtual bool IsRunnable() =0;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,6 +229,7 @@ typedef struct sp_debug_symbol_s
|
|||||||
typedef int (*SPVM_DEBUGBREAK)(struct sp_context_s *, uint32_t, uint32_t);
|
typedef int (*SPVM_DEBUGBREAK)(struct sp_context_s *, uint32_t, uint32_t);
|
||||||
|
|
||||||
#define SPFLAG_PLUGIN_DEBUG (1<<0) /**< plugin is in debug mode */
|
#define SPFLAG_PLUGIN_DEBUG (1<<0) /**< plugin is in debug mode */
|
||||||
|
#define SPFLAG_PLUGIN_PAUSED (1<<1) /**< plugin is "paused" (blocked from executing) */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This is the heart of the VM. It contains all of the runtime
|
* @brief This is the heart of the VM. It contains all of the runtime
|
||||||
|
Loading…
Reference in New Issue
Block a user