Remove native override API (bug 5852 part 1, r=ds).
--HG-- extra : rebase_source : 9df0399c88721b63667a9b0b5dca0eb20168117a
This commit is contained in:
parent
4dc5d0e12f
commit
0e677fb3a2
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourcePawn
|
* SourcePawn
|
||||||
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2009 AlliedModders LLC. All rights reserved.
|
||||||
@ -69,30 +69,15 @@ INativeInvoker *NativeInterface::CreateInvoker()
|
|||||||
|
|
||||||
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
|
bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
|
||||||
{
|
{
|
||||||
NativeEntry *entry;
|
NativeEntry *entry = g_ShareSys.FindNative(name);
|
||||||
|
if (!entry)
|
||||||
entry = g_ShareSys.FindNative(name);
|
|
||||||
if (entry == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
native = NULL;
|
if (!entry->owner || !entry->func)
|
||||||
if (entry->replacement.owner != NULL)
|
|
||||||
{
|
|
||||||
native = entry->replacement.func;
|
|
||||||
}
|
|
||||||
else if (entry->owner != NULL)
|
|
||||||
{
|
|
||||||
native = entry->func;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (native == NULL)
|
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
this->pContext = pContext;
|
native_ = entry->func;
|
||||||
|
context_ = pContext;
|
||||||
|
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
@ -184,15 +169,13 @@ int NativeInvoker::_PushString(const char *string, int sz_flags, int cp_flags, s
|
|||||||
|
|
||||||
void NativeInvoker::Cancel()
|
void NativeInvoker::Cancel()
|
||||||
{
|
{
|
||||||
if (pContext == NULL)
|
if (context_ == NULL)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_errorstate = SP_ERROR_NONE;
|
m_errorstate = SP_ERROR_NONE;
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
pContext = NULL;
|
context_ = NULL;
|
||||||
native = NULL;
|
native_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NativeInvoker::SetError(int err)
|
int NativeInvoker::SetError(int err)
|
||||||
@ -205,10 +188,8 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
{
|
{
|
||||||
int err = SP_ERROR_NONE;
|
int err = SP_ERROR_NONE;
|
||||||
|
|
||||||
if (pContext == NULL)
|
if (context_ == NULL)
|
||||||
{
|
|
||||||
return SP_ERROR_INVALID_NATIVE;
|
return SP_ERROR_INVALID_NATIVE;
|
||||||
}
|
|
||||||
|
|
||||||
if (m_errorstate != SP_ERROR_NONE)
|
if (m_errorstate != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
@ -225,7 +206,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//This is for re-entrancy!
|
//This is for re-entrancy!
|
||||||
IPluginContext *ctx = pContext;
|
IPluginContext *ctx = context_;
|
||||||
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
|
cell_t _temp_params[SP_MAX_EXEC_PARAMS + 1];
|
||||||
cell_t *temp_params = &_temp_params[1];
|
cell_t *temp_params = &_temp_params[1];
|
||||||
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
|
ParamInfo temp_info[SP_MAX_EXEC_PARAMS];
|
||||||
@ -239,7 +220,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
|
memcpy(temp_info, m_info, numparams * sizeof(ParamInfo));
|
||||||
}
|
}
|
||||||
m_curparam = 0;
|
m_curparam = 0;
|
||||||
pContext = NULL;
|
context_ = NULL;
|
||||||
|
|
||||||
/* Initialize 0th parameter */
|
/* Initialize 0th parameter */
|
||||||
_temp_params[0] = numparams;
|
_temp_params[0] = numparams;
|
||||||
@ -324,7 +305,7 @@ int NativeInvoker::Invoke(cell_t *result)
|
|||||||
/* Make the call if we can */
|
/* Make the call if we can */
|
||||||
if (err == SP_ERROR_NONE)
|
if (err == SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
*result = native(ctx, _temp_params);
|
*result = native_(ctx, _temp_params);
|
||||||
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
|
if (ctx->GetLastNativeError() != SP_ERROR_NONE)
|
||||||
{
|
{
|
||||||
docopies = false;
|
docopies = false;
|
||||||
|
@ -75,8 +75,8 @@ private:
|
|||||||
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
int _PushString(const char *string, int sz_flags, int cp_flags, size_t len);
|
||||||
int SetError(int err);
|
int SetError(int err);
|
||||||
private:
|
private:
|
||||||
IPluginContext *pContext;
|
IPluginContext *context_;
|
||||||
SPVM_NATIVE_FUNC native;
|
SPVM_NATIVE_FUNC native_;
|
||||||
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;
|
||||||
|
@ -123,16 +123,6 @@ void CNativeOwner::DropEverything()
|
|||||||
iter = m_WeakRefs.erase(iter);
|
iter = m_WeakRefs.erase(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Unmark our replacement natives */
|
|
||||||
ntv_iter = m_ReplacedNatives.begin();
|
|
||||||
while (ntv_iter != m_ReplacedNatives.end())
|
|
||||||
{
|
|
||||||
pEntry = (*ntv_iter);
|
|
||||||
pEntry->replacement.func = NULL;
|
|
||||||
pEntry->replacement.owner = NULL;
|
|
||||||
ntv_iter = m_ReplacedNatives.erase(ntv_iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Strip all of our natives from the cache */
|
/* Strip all of our natives from the cache */
|
||||||
ntv_iter = m_Natives.begin();
|
ntv_iter = m_Natives.begin();
|
||||||
while (ntv_iter != m_Natives.end())
|
while (ntv_iter != m_Natives.end())
|
||||||
@ -167,8 +157,3 @@ void CNativeOwner::DropRefsTo(CPlugin *pPlugin)
|
|||||||
m_Dependents.remove(pPlugin);
|
m_Dependents.remove(pPlugin);
|
||||||
DropWeakRefsTo(pPlugin);
|
DropWeakRefsTo(pPlugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNativeOwner::AddReplacedNative(NativeEntry *pEntry)
|
|
||||||
{
|
|
||||||
m_ReplacedNatives.push_back(pEntry);
|
|
||||||
}
|
|
||||||
|
@ -47,7 +47,6 @@ public:
|
|||||||
void AddDependent(CPlugin *pPlugin);
|
void AddDependent(CPlugin *pPlugin);
|
||||||
void AddWeakRef(const WeakNative & ref);
|
void AddWeakRef(const WeakNative & ref);
|
||||||
void DropRefsTo(CPlugin *pPlugin);
|
void DropRefsTo(CPlugin *pPlugin);
|
||||||
void AddReplacedNative(NativeEntry *pEntry);
|
|
||||||
private:
|
private:
|
||||||
void DropWeakRefsTo(CPlugin *pPlugin);
|
void DropWeakRefsTo(CPlugin *pPlugin);
|
||||||
void UnbindWeakRef(const WeakNative & ref);
|
void UnbindWeakRef(const WeakNative & ref);
|
||||||
@ -56,7 +55,6 @@ protected:
|
|||||||
unsigned int m_nMarkSerial;
|
unsigned int m_nMarkSerial;
|
||||||
List<WeakNative> m_WeakRefs;
|
List<WeakNative> m_WeakRefs;
|
||||||
List<NativeEntry *> m_Natives;
|
List<NativeEntry *> m_Natives;
|
||||||
List<NativeEntry *> m_ReplacedNatives;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CNativeOwner g_CoreNatives;
|
extern CNativeOwner g_CoreNatives;
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "common_logic.h"
|
#include "common_logic.h"
|
||||||
#include "PluginSys.h"
|
#include "PluginSys.h"
|
||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
ShareSystem g_ShareSys;
|
ShareSystem g_ShareSys;
|
||||||
static unsigned int g_mark_serial = 0;
|
static unsigned int g_mark_serial = 0;
|
||||||
@ -255,34 +256,7 @@ void ShareSystem::RegisterLibrary(IExtension *myself, const char *name)
|
|||||||
|
|
||||||
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
|
void ShareSystem::OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
assert(false);
|
||||||
NativeEntry *pEntry;
|
|
||||||
CNativeOwner *pOwner;
|
|
||||||
|
|
||||||
pOwner = g_Extensions.GetNativeOwner(myself);
|
|
||||||
|
|
||||||
for (i = 0; natives[i].func != NULL && natives[i].name != NULL; i++)
|
|
||||||
{
|
|
||||||
if ((pEntry = FindNative(natives[i].name)) == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pEntry->owner != &g_CoreNatives)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pEntry->replacement.owner != NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now it's safe to add the override */
|
|
||||||
pEntry->replacement.func = natives[i].func;
|
|
||||||
pEntry->replacement.owner = pOwner;
|
|
||||||
pOwner->AddReplacedNative(pEntry);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeEntry *ShareSystem::FindNative(const char *name)
|
NativeEntry *ShareSystem::FindNative(const char *name)
|
||||||
@ -295,7 +269,6 @@ NativeEntry *ShareSystem::FindNative(const char *name)
|
|||||||
|
|
||||||
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
||||||
{
|
{
|
||||||
NativeEntry *pEntry;
|
|
||||||
sp_native_t *native;
|
sp_native_t *native;
|
||||||
uint32_t i, native_count;
|
uint32_t i, native_count;
|
||||||
IPluginContext *pContext;
|
IPluginContext *pContext;
|
||||||
@ -310,34 +283,19 @@ void ShareSystem::BindNativesToPlugin(CPlugin *pPlugin, bool bCoreOnly)
|
|||||||
for (i = 0; i < native_count; i++)
|
for (i = 0; i < native_count; i++)
|
||||||
{
|
{
|
||||||
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
if (pContext->GetNativeByIndex(i, &native) != SP_ERROR_NONE)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're bound, check if there is a replacement available.
|
// If we're already bound, no need to do anything else.
|
||||||
* If not, this native is totally finalized.
|
|
||||||
*/
|
|
||||||
if (native->status == SP_NATIVE_BOUND)
|
if (native->status == SP_NATIVE_BOUND)
|
||||||
{
|
|
||||||
pEntry = (NativeEntry *)native->user;
|
|
||||||
assert(pEntry != NULL);
|
|
||||||
if (pEntry->replacement.owner == NULL
|
|
||||||
|| (pEntry->replacement.owner != NULL
|
|
||||||
&& pEntry->replacement.func == native->pfn))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Otherwise, the native must be in our cache. */
|
|
||||||
else if ((pEntry = FindNative(native->name)) == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
/* Otherwise, the native must be in our cache. */
|
||||||
|
NativeEntry *pEntry = FindNative(native->name);
|
||||||
|
if (!pEntry)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (bCoreOnly && pEntry->owner != &g_CoreNatives)
|
if (bCoreOnly && pEntry->owner != &g_CoreNatives)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
BindNativeToPlugin(pPlugin, native, i, pEntry);
|
BindNativeToPlugin(pPlugin, native, i, pEntry);
|
||||||
}
|
}
|
||||||
@ -377,49 +335,39 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
|
|||||||
native->status = SP_NATIVE_BOUND;
|
native->status = SP_NATIVE_BOUND;
|
||||||
native->user = pEntry;
|
native->user = pEntry;
|
||||||
|
|
||||||
/* See if a replacement is available. */
|
/* Perform a bind. */
|
||||||
if (pEntry->replacement.owner != NULL)
|
native->pfn = pEntry->func;
|
||||||
{
|
|
||||||
/* Perform a replacement bind. */
|
|
||||||
native->pfn = pEntry->replacement.func;
|
|
||||||
pEntry->replacement.owner->AddWeakRef(WeakNative(pPlugin, index, pEntry));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Perform a normal bind. */
|
|
||||||
native->pfn = pEntry->func;
|
|
||||||
|
|
||||||
/* We don't bother with dependency crap if the owner is Core. */
|
/* We don't bother with dependency crap if the owner is Core. */
|
||||||
if (pEntry->owner != &g_CoreNatives)
|
if (pEntry->owner != &g_CoreNatives)
|
||||||
|
{
|
||||||
|
/* The native is optional, this is a special case */
|
||||||
|
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
|
||||||
{
|
{
|
||||||
/* The native is optional, this is a special case */
|
/* Only add if there is a valid owner. */
|
||||||
if ((native->flags & SP_NTVFLAG_OPTIONAL) == SP_NTVFLAG_OPTIONAL)
|
if (pEntry->owner != NULL)
|
||||||
{
|
{
|
||||||
/* Only add if there is a valid owner. */
|
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
|
||||||
if (pEntry->owner != NULL)
|
|
||||||
{
|
|
||||||
pEntry->owner->AddWeakRef(WeakNative(pPlugin, index));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
native->status = SP_NATIVE_UNBOUND;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Otherwise, we're a strong dependent and not a weak one */
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* See if this has already been marked as a dependent.
|
native->status = SP_NATIVE_UNBOUND;
|
||||||
* If it has, it means this relationship has already occurred,
|
}
|
||||||
* and there is no reason to do it again.
|
}
|
||||||
*/
|
/* Otherwise, we're a strong dependent and not a weak one */
|
||||||
if (pEntry->owner != pPlugin->ToNativeOwner()
|
else
|
||||||
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
|
{
|
||||||
{
|
/* See if this has already been marked as a dependent.
|
||||||
/* This has not been marked as a dependency yet */
|
* If it has, it means this relationship has already occurred,
|
||||||
//pPlugin->AddDependency(pEntry->owner);
|
* and there is no reason to do it again.
|
||||||
pEntry->owner->AddDependent(pPlugin);
|
*/
|
||||||
pEntry->owner->SetMarkSerial(g_mark_serial);
|
if (pEntry->owner != pPlugin->ToNativeOwner()
|
||||||
}
|
&& pEntry->owner->GetMarkSerial() != g_mark_serial)
|
||||||
|
{
|
||||||
|
/* This has not been marked as a dependency yet */
|
||||||
|
//pPlugin->AddDependency(pEntry->owner);
|
||||||
|
pEntry->owner->AddDependent(pPlugin);
|
||||||
|
pEntry->owner->SetMarkSerial(g_mark_serial);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,8 +384,6 @@ NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_native
|
|||||||
pEntry->owner = pOwner;
|
pEntry->owner = pOwner;
|
||||||
pEntry->name = ntv->name;
|
pEntry->name = ntv->name;
|
||||||
pEntry->func = ntv->func;
|
pEntry->func = ntv->func;
|
||||||
pEntry->replacement.func = NULL;
|
|
||||||
pEntry->replacement.owner = NULL;
|
|
||||||
pEntry->fake = NULL;
|
pEntry->fake = NULL;
|
||||||
|
|
||||||
m_NtvCache.insert(ntv->name, pEntry);
|
m_NtvCache.insert(ntv->name, pEntry);
|
||||||
@ -481,8 +427,6 @@ void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
|
|||||||
pEntry->func = NULL;
|
pEntry->func = NULL;
|
||||||
pEntry->name = NULL;
|
pEntry->name = NULL;
|
||||||
pEntry->owner = NULL;
|
pEntry->owner = NULL;
|
||||||
pEntry->replacement.func = NULL;
|
|
||||||
pEntry->replacement.owner = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
|
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
|
||||||
@ -518,8 +462,6 @@ NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name
|
|||||||
pEntry->func = gate;
|
pEntry->func = gate;
|
||||||
pEntry->name = pFake->name;
|
pEntry->name = pFake->name;
|
||||||
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
|
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
|
||||||
pEntry->replacement.func = NULL;
|
|
||||||
pEntry->replacement.owner = NULL;
|
|
||||||
|
|
||||||
return pEntry;
|
return pEntry;
|
||||||
}
|
}
|
||||||
@ -582,18 +524,13 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
|
|||||||
}
|
}
|
||||||
|
|
||||||
NativeEntry *entry = FindNative(name);
|
NativeEntry *entry = FindNative(name);
|
||||||
if (entry == NULL)
|
if (!entry)
|
||||||
return FeatureStatus_Unknown;
|
return FeatureStatus_Unknown;
|
||||||
|
|
||||||
if ((entry->replacement.owner != NULL || entry->owner != NULL) &&
|
if (entry->owner && entry->func)
|
||||||
(entry->replacement.func != NULL || entry->func != NULL))
|
|
||||||
{
|
|
||||||
return FeatureStatus_Available;
|
return FeatureStatus_Available;
|
||||||
}
|
|
||||||
else
|
return FeatureStatus_Unavailable;
|
||||||
{
|
|
||||||
return FeatureStatus_Unavailable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FeatureStatus ShareSystem::TestCap(const char *name)
|
FeatureStatus ShareSystem::TestCap(const char *name)
|
||||||
|
@ -65,12 +65,6 @@ class CNativeOwner;
|
|||||||
struct NativeEntry;
|
struct NativeEntry;
|
||||||
class CPlugin;
|
class CPlugin;
|
||||||
|
|
||||||
struct ReplaceNative
|
|
||||||
{
|
|
||||||
CNativeOwner *owner;
|
|
||||||
SPVM_NATIVE_FUNC func;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FakeNative
|
struct FakeNative
|
||||||
{
|
{
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -83,7 +77,6 @@ struct NativeEntry
|
|||||||
CNativeOwner *owner;
|
CNativeOwner *owner;
|
||||||
SPVM_NATIVE_FUNC func;
|
SPVM_NATIVE_FUNC func;
|
||||||
const char *name;
|
const char *name;
|
||||||
ReplaceNative replacement;
|
|
||||||
FakeNative *fake;
|
FakeNative *fake;
|
||||||
|
|
||||||
static inline bool matches(const char *name, const NativeEntry *entry)
|
static inline bool matches(const char *name, const NativeEntry *entry)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* vim: set ts=4 :
|
* vim: set ts=4 sw=4 tw=99 noet :
|
||||||
* =============================================================================
|
* =============================================================================
|
||||||
* SourceMod
|
* SourceMod
|
||||||
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
||||||
@ -234,23 +234,10 @@ namespace SourceMod
|
|||||||
virtual void RegisterLibrary(IExtension *myself, const char *name) =0;
|
virtual void RegisterLibrary(IExtension *myself, const char *name) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds natives that will override Core natives when called.
|
* @brief Deprecated. Does nothing.
|
||||||
*
|
*
|
||||||
* A Core version of each native must exist. If one does not, then
|
* @param myself Ignored.
|
||||||
* Core will simply ignore that entry. No more than one override
|
* @param natives Ignored.
|
||||||
* can exist on a given native.
|
|
||||||
*
|
|
||||||
* Override natives represent a weak coupling. If the extension is
|
|
||||||
* unloaded, the native will be re-bound to the Core version. If
|
|
||||||
* the extension is loaded after plugins are loaded, the override
|
|
||||||
* will not take effect until those plugins are reloaded.
|
|
||||||
*
|
|
||||||
* @param myself Identity token of parent object.
|
|
||||||
* @param natives Array of natives to add. The last entry in
|
|
||||||
* the array must be filled with NULLs to
|
|
||||||
* terminate the array. The array must be static
|
|
||||||
* as Core will cache the pointer for the
|
|
||||||
* lifetime of the extension.
|
|
||||||
*/
|
*/
|
||||||
virtual void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;
|
virtual void OverrideNatives(IExtension *myself, const sp_nativeinfo_t *natives) =0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user