- added callbacks for libraries becoming available

- fixed MarkNTVOptional requring native to exist
- fixed a bug where it looks like plugins could not be paused

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401130
This commit is contained in:
David Anderson 2007-07-16 02:06:02 +00:00
parent 399fb8a8e8
commit 4ce48512b1
4 changed files with 161 additions and 7 deletions

View File

@ -339,7 +339,8 @@ static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *param
pContext->LocalToString(params[1], &name);
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
{
return pContext->ThrowNativeError("Unable to find native \"%s\"", name);
/* Oops! This HAS to silently fail! */
return 0;
}
ctx->natives[idx].flags |= SP_NTVFLAG_OPTIONAL;
@ -359,6 +360,14 @@ static cell_t RegPluginLibrary(IPluginContext *pContext, const cell_t *params)
return 1;
}
static cell_t LibraryExists(IPluginContext *pContext, const cell_t *params)
{
char *str;
pContext->LocalToString(params[1], &str);
return g_PluginSys.LibraryExists(str) ? 1 : 0;
}
REGISTER_NATIVES(coreNatives)
{
{"AutoExecConfig", AutoExecConfig},
@ -376,5 +385,6 @@ REGISTER_NATIVES(coreNatives)
{"FormatTime", FormatTime},
{"MarkNativeAsOptional", MarkNativeAsOptional},
{"RegPluginLibrary", RegPluginLibrary},
{"LibraryExists", LibraryExists},
{NULL, NULL},
};

View File

@ -425,15 +425,31 @@ bool CPlugin::IsDebugging()
return ((m_ctx.ctx->flags & SP_FLAG_DEBUG) == SP_FLAG_DEBUG);
}
void CPlugin::LibraryActions(bool dropping)
{
List<String>::iterator iter;
for (iter = m_Libraries.begin();
iter != m_Libraries.end();
iter++)
{
g_PluginSys.OnLibraryAction((*iter).c_str(), dropping);
}
}
bool CPlugin::SetPauseState(bool paused)
{
if (paused && GetStatus() != Plugin_Paused)
if (paused && GetStatus() != Plugin_Running)
{
return false;
} else if (!paused && GetStatus() != Plugin_Running) {
} else if (!paused && GetStatus() != Plugin_Paused) {
return false;
}
if (paused)
{
LibraryActions(true);
}
IPluginFunction *pFunction = m_ctx.base->GetFunctionByName("OnPluginPauseChange");
if (pFunction)
{
@ -453,6 +469,11 @@ bool CPlugin::SetPauseState(bool paused)
g_PluginSys._SetPauseState(this, paused);
if (!paused)
{
LibraryActions(false);
}
return true;
}
@ -1253,6 +1274,15 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
}
}
/* Go through our libraries and tell other plugins they're added */
List<String>::iterator s_iter;
for (s_iter = pPlugin->m_Libraries.begin();
s_iter != pPlugin->m_Libraries.end();
s_iter++)
{
OnLibraryAction((*s_iter).c_str(), false);
}
return true;
}
@ -1395,6 +1425,15 @@ bool CPluginManager::UnloadPlugin(IPlugin *plugin)
m_plugins.remove(pPlugin);
sm_trie_delete(m_LoadLookup, pPlugin->m_filename);
/* Go through our libraries and tell other plugins they're gone */
List<String>::iterator s_iter;
for (s_iter = pPlugin->m_Libraries.begin();
s_iter != pPlugin->m_Libraries.end();
s_iter++)
{
OnLibraryAction((*s_iter).c_str(), true);
}
/* Go through all dependent plugins and tell them this plugin is now gone */
List<CPlugin *>::iterator pl_iter;
CPlugin *pOther;
@ -2190,9 +2229,88 @@ CPlugin *CPluginManager::GetPluginFromIdentity(IdentityToken_t *pToken)
return (CPlugin *)(pToken->ptr);
}
void CPluginManager::ExecAndGenPluginConfs()
void CPluginManager::OnLibraryAction(const char *lib, bool drop)
{
List<CPlugin *>::iterator iter;
//for (iter =
struct _pl
{
cell_t name;
cell_t file;
cell_t required;
} *plc;
const char *name = drop ? "OnLibraryRemoved" : "OnLibraryAdded";
for (iter=m_plugins.begin();
iter!=m_plugins.end();
iter++)
{
CPlugin *pl = (*iter);
if (pl->GetStatus() != Plugin_Running)
{
continue;
}
IPluginContext *pContext = pl->GetBaseContext();
IPluginFunction *pf = pContext->GetFunctionByName(name);
if (!pf)
{
continue;
}
sp_context_t *ctx = pContext->GetContext();
uint32_t num_vars = pContext->GetPubVarsNum();
for (uint32_t i=0; i<num_vars; i++)
{
sp_pubvar_t *pubvar;
if (pContext->GetPubvarByIndex(i, &pubvar) != SP_ERROR_NONE)
{
continue;
}
if (strncmp(pubvar->name, "__pl_", 5) != 0)
{
continue;
}
plc = (_pl *)pubvar->offs;
if (plc->required)
{
continue;
}
char *str;
pContext->LocalToString(plc->name, &str);
if (strcmp(str, lib) != 0)
{
continue;
}
pf->PushString(lib);
pf->Execute(NULL);
}
}
}
bool CPluginManager::LibraryExists(const char *lib)
{
List<CPlugin *>::iterator iter;
for (iter=m_plugins.begin();
iter!=m_plugins.end();
iter++)
{
CPlugin *pl = (*iter);
if (pl->GetStatus() != Plugin_Running)
{
continue;
}
List<String>::iterator s_iter;
for (s_iter = pl->m_Libraries.begin();
s_iter != pl->m_Libraries.end();
s_iter++)
{
if ((*s_iter).compare(lib) == 0)
{
return true;
}
}
}
return false;
}

View File

@ -250,6 +250,7 @@ public:
{
m_Libraries.push_back(name);
}
void LibraryActions(bool dropping);
protected:
void UpdateInfo();
void SetTimeStamp(time_t t);
@ -398,6 +399,9 @@ public:
void Shutdown();
void OnLibraryAction(const char *lib, bool drop);
bool LibraryExists(const char *lib);
private:
LoadRes _LoadPlugin(CPlugin **pPlugin, const char *path, bool debug, PluginType type, char error[], size_t maxlength);
@ -434,8 +438,6 @@ private:
bool FindOrRequirePluginDeps(CPlugin *pPlugin, char *error, size_t maxlength);
void _SetPauseState(CPlugin *pPlugin, bool pause);
void ExecAndGenPluginConfs();
protected:
/**
* Caching internal objects

View File

@ -348,5 +348,29 @@ native MarkNativeAsOptional(const String:name[]);
*/
native RegPluginLibrary(const String:name[]);
/**
* Returns whether a library exists.
*
* @param name Library name.
* @return True if exists, false otherwise.
*/
native bool:LibraryExists(const String:name[]);
/**
* Called after a library (plugin) is added that the
* current plugin references optionally.
*
* @param name Library name.
*/
forward OnLibraryAdded(const String:name[]);
/**
* Called right before a library (plugin) is removed that the
* current plugin references optionally.
*
* @param name Library name.
*/
forward OnLibraryRemoved(const String:name[]);
#include <helpers>
#include <entity>