added experimental optional natives (part 1)
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401095
This commit is contained in:
parent
5b8ffc08eb
commit
8a8e6ef594
@ -330,20 +330,44 @@ static cell_t AutoExecConfig(IPluginContext *pContext, const cell_t *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t MarkNativeAsOptional(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *name;
|
||||
uint32_t idx;
|
||||
sp_context_t *ctx = pContext->GetContext();
|
||||
CPlugin *pl = g_PluginSys.GetPluginByCtx(ctx);
|
||||
|
||||
if (!pl->IsInAskPluginLoad())
|
||||
{
|
||||
return pContext->ThrowNativeError("Calling MarkNativeAsOptional outside AskPluginLoad is not allowed");
|
||||
}
|
||||
|
||||
pContext->LocalToString(params[1], &name);
|
||||
if (pContext->FindNativeByName(name, &idx) != SP_ERROR_NONE)
|
||||
{
|
||||
return pContext->ThrowNativeError("Unable to find native \"%s\"", name);
|
||||
}
|
||||
|
||||
ctx->natives[idx].flags |= SP_NTVFLAG_OPTIONAL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(coreNatives)
|
||||
{
|
||||
{"AutoExecConfig", AutoExecConfig},
|
||||
{"GetPluginFilename", GetPluginFilename},
|
||||
{"GetPluginInfo", GetPluginInfo},
|
||||
{"GetPluginIterator", GetPluginIterator},
|
||||
{"GetPluginStatus", GetPluginStatus},
|
||||
{"GetSysTickCount", GetSysTickCount},
|
||||
{"GetTime", GetTime},
|
||||
{"IsPluginDebugging", IsPluginDebugging},
|
||||
{"MorePlugins", MorePlugins},
|
||||
{"ReadPlugin", ReadPlugin},
|
||||
{"ThrowError", ThrowError},
|
||||
{"SetFailState", SetFailState},
|
||||
{"FormatTime", FormatTime},
|
||||
{NULL, NULL},
|
||||
{"AutoExecConfig", AutoExecConfig},
|
||||
{"GetPluginFilename", GetPluginFilename},
|
||||
{"GetPluginInfo", GetPluginInfo},
|
||||
{"GetPluginIterator", GetPluginIterator},
|
||||
{"GetPluginStatus", GetPluginStatus},
|
||||
{"GetSysTickCount", GetSysTickCount},
|
||||
{"GetTime", GetTime},
|
||||
{"IsPluginDebugging", IsPluginDebugging},
|
||||
{"MorePlugins", MorePlugins},
|
||||
{"ReadPlugin", ReadPlugin},
|
||||
{"ThrowError", ThrowError},
|
||||
{"SetFailState", SetFailState},
|
||||
{"FormatTime", FormatTime},
|
||||
{"MarkNativeAsOptional", MarkNativeAsOptional},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -529,13 +529,19 @@ void CExtensionManager::BindAllNativesToPlugin(IPlugin *pPlugin)
|
||||
n_iter++)
|
||||
{
|
||||
natives = (*n_iter);
|
||||
uint32_t idx;
|
||||
unsigned int i=0;
|
||||
while (natives[i].func != NULL && natives[i].name != NULL)
|
||||
{
|
||||
if (pContext->BindNative(&natives[i++]) == SP_ERROR_NONE)
|
||||
if (pContext->BindNative(&natives[i]) == SP_ERROR_NONE)
|
||||
{
|
||||
set = true;
|
||||
pContext->FindNativeByName(natives[i].name, &idx);
|
||||
if (!(pContext->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
||||
{
|
||||
set = true;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (set && (pExt->m_Plugins.find(pPlugin) == pExt->m_Plugins.end()))
|
||||
|
@ -357,15 +357,19 @@ bool CPlugin::Call_AskPluginLoad(char *error, size_t maxlength)
|
||||
return true;
|
||||
}
|
||||
|
||||
m_IsInAskPluginLoad = true;
|
||||
pFunction->PushCell(m_handle);
|
||||
pFunction->PushCell(g_PluginSys.IsLateLoadTime() ? 1 : 0);
|
||||
pFunction->PushStringEx(error, maxlength, 0, SM_PARAM_COPYBACK);
|
||||
pFunction->PushCell(maxlength);
|
||||
if ((err=pFunction->Execute(&result)) != SP_ERROR_NONE)
|
||||
{
|
||||
m_IsInAskPluginLoad = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_IsInAskPluginLoad = false;
|
||||
|
||||
if (!result || m_status != Plugin_Loaded)
|
||||
{
|
||||
return false;
|
||||
@ -1098,7 +1102,8 @@ bool CPluginManager::RunSecondPass(CPlugin *pPlugin, char *error, size_t maxleng
|
||||
break;
|
||||
}
|
||||
if (native->status == SP_NATIVE_UNBOUND
|
||||
&& native->name[0] != '@')
|
||||
&& native->name[0] != '@'
|
||||
&& !(native->flags & SP_NTVFLAG_OPTIONAL))
|
||||
{
|
||||
if (error)
|
||||
{
|
||||
@ -1176,7 +1181,7 @@ void CPluginManager::TryRefreshNatives(CPlugin *pPlugin)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (native->status == SP_NATIVE_UNBOUND)
|
||||
if (native->status == SP_NATIVE_UNBOUND && !(native->flags & SP_NTVFLAG_OPTIONAL))
|
||||
{
|
||||
pPlugin->SetErrorState(Plugin_Error, "Native not found: %s", native->name);
|
||||
return;
|
||||
@ -1213,6 +1218,12 @@ void CPluginManager::AddFakeNativesToPlugin(CPlugin *pPlugin)
|
||||
native.func = pNative->func;
|
||||
if (pContext->BindNative(&native) == SP_ERROR_NONE)
|
||||
{
|
||||
uint32_t idx;
|
||||
pContext->FindNativeByName(native.name, &idx);
|
||||
if (!(pPlugin->GetContext()->natives[idx].flags & SP_NTVFLAG_OPTIONAL))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/* Add us as a dependency, but we're careful not to do this circularly! */
|
||||
if (pNative->ctx != pContext)
|
||||
{
|
||||
|
@ -234,6 +234,10 @@ public:
|
||||
void AddConfig(bool autoCreate, const char *cfg, const char *folder);
|
||||
unsigned int GetConfigCount();
|
||||
AutoConfig *GetConfig(unsigned int i);
|
||||
inline bool IsInAskPluginLoad()
|
||||
{
|
||||
return m_IsInAskPluginLoad;
|
||||
}
|
||||
protected:
|
||||
void UpdateInfo();
|
||||
void SetTimeStamp(time_t t);
|
||||
@ -258,6 +262,7 @@ private:
|
||||
Trie *m_pProps;
|
||||
bool m_FakeNativesMissing;
|
||||
CVector<AutoConfig *> m_configs;
|
||||
bool m_IsInAskPluginLoad;
|
||||
};
|
||||
|
||||
class CPluginManager :
|
||||
|
@ -171,6 +171,8 @@ typedef struct sp_pubvar_s
|
||||
#define SP_NATIVE_UNBOUND (0) /**< Native is undefined */
|
||||
#define SP_NATIVE_BOUND (1) /**< Native is bound */
|
||||
|
||||
#define SP_NTVFLAG_OPTIONAL (1<<0) /**< Native is optional */
|
||||
|
||||
/**
|
||||
* @brief Native lookup table, by default names point back to the sp_plugin_infotab_t structure.
|
||||
*/
|
||||
@ -179,6 +181,7 @@ typedef struct sp_native_s
|
||||
SPVM_NATIVE_FUNC pfn; /**< Function pointer */
|
||||
const char * name; /**< Name of function */
|
||||
uint32_t status; /**< Status flags */
|
||||
uint32_t flags; /**< Native flags */
|
||||
} sp_native_t;
|
||||
|
||||
/**
|
||||
|
@ -2445,6 +2445,7 @@ jit_rewind:
|
||||
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
|
||||
ctx->natives[iter].pfn = &InvalidNative;
|
||||
ctx->natives[iter].status = SP_NATIVE_UNBOUND;
|
||||
ctx->natives[iter].flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user