Simplify NativeEntry state (bug 5852 part 3, r=ds).

--HG--
extra : rebase_source : e80ed1c3b3af0b48fff6632eb131ca534a2c2885
This commit is contained in:
David Anderson 2013-08-30 10:14:18 -07:00
parent 140436c2cb
commit 3da646f913
5 changed files with 73 additions and 59 deletions

View File

@ -73,10 +73,10 @@ bool NativeInvoker::Start(IPluginContext *pContext, const char *name)
if (!entry)
return false;
if (!entry->owner || !entry->func)
if (!entry->owner || !entry->func())
return false;
native_ = entry->func;
native_ = entry->func();
context_ = pContext;
m_curparam = 0;

View File

@ -97,7 +97,7 @@ void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
*/
else
{
native->pfn = ref.entry->func;
native->pfn = ref.entry->func();
}
}
}
@ -125,7 +125,7 @@ void CNativeOwner::DropEverything()
List<NativeEntry *>::iterator ntv_iter = m_Natives.begin();
while (ntv_iter != m_Natives.end())
{
g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name);
g_ShareSys.ClearNativeFromCache(this, (*ntv_iter)->name());
ntv_iter = m_Natives.erase(ntv_iter);
}
}

View File

@ -625,7 +625,7 @@ void CPlugin::DependencyDropped(CPlugin *pOwner)
{
pNative = (*iter);
/* Find this native! */
if (m_pRuntime->FindNativeByName(pNative->name, &idx) != SP_ERROR_NONE)
if (m_pRuntime->FindNativeByName(pNative->name(), &idx) != SP_ERROR_NONE)
{
continue;
}

View File

@ -309,7 +309,7 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
pContext = pPlugin->GetBaseContext();
if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE)
if (pContext->FindNativeByName(pEntry->name(), &i) != SP_ERROR_NONE)
{
return;
}
@ -336,7 +336,7 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
native->user = pEntry;
/* Perform a bind. */
native->pfn = pEntry->func;
native->pfn = pEntry->func();
/* We don't bother with dependency crap if the owner is Core. */
if (pEntry->owner != &g_CoreNatives)
@ -379,90 +379,63 @@ NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_native
if ((pEntry = FindNative(ntv->name)) == NULL)
{
pEntry = new NativeEntry;
pEntry->owner = pOwner;
pEntry->name = ntv->name;
pEntry->func = ntv->func;
pEntry->fake = NULL;
pEntry = new NativeEntry(pOwner, ntv);
m_NtvCache.insert(ntv->name, pEntry);
return pEntry;
}
if (pEntry->owner != NULL)
{
return NULL;
}
pEntry->owner = pOwner;
pEntry->func = ntv->func;
pEntry->name = ntv->name;
pEntry->native = NULL;
return pEntry;
}
FakeNative::~FakeNative()
{
g_pSourcePawn2->DestroyFakeNative(gate);
}
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
{
NativeEntry *pEntry;
if ((pEntry = FindNative(name)) == NULL)
{
return;
}
if (pEntry->owner != pOwner)
{
return;
}
if (pEntry->fake != NULL)
{
g_pSourcePawn2->DestroyFakeNative(pEntry->func);
delete pEntry->fake;
pEntry->fake = NULL;
}
pEntry->func = NULL;
pEntry->name = NULL;
pEntry->fake = NULL;
pEntry->native = NULL;
pEntry->owner = NULL;
}
NativeEntry *ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
{
FakeNative *pFake;
NativeEntry *pEntry;
SPVM_NATIVE_FUNC gate;
if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
{
return NULL;
}
pFake = new FakeNative;
ke::AutoPtr<FakeNative> fake(new FakeNative(name, pFunc));
if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL)
{
delete pFake;
fake->gate = g_pSourcePawn2->CreateFakeNative(func, fake);
if (!fake->gate)
return NULL;
}
if (pEntry == NULL)
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
if (!pEntry)
{
pEntry = new NativeEntry;
pEntry = new NativeEntry(owner, fake.take());
m_NtvCache.insert(name, pEntry);
} else {
pEntry->owner = owner;
pEntry->fake = fake.take();
}
pFake->call = pFunc;
pFake->ctx = pFunc->GetParentContext();
smcore.strncopy(pFake->name, name, sizeof(pFake->name));
pEntry->fake = pFake;
pEntry->func = gate;
pEntry->name = pFake->name;
pEntry->owner = g_PluginSys.GetPluginByCtx(pFake->ctx->GetContext());
return pEntry;
}
@ -527,7 +500,7 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
if (!entry)
return FeatureStatus_Unknown;
if (entry->owner && entry->func)
if (entry->owner)
return FeatureStatus_Available;
return FeatureStatus_Unavailable;

View File

@ -34,6 +34,8 @@
#include <IShareSys.h>
#include <IHandleSys.h>
#include <am-string.h>
#include <am-utility.h>
#include <sh_list.h>
#include <sm_stringhashmap.h>
#include <sm_namehashset.h>
@ -67,21 +69,60 @@ class CPlugin;
struct FakeNative
{
char name[64];
FakeNative(const char *name, IPluginFunction *fun)
: name(name),
ctx(fun->GetParentContext()),
call(fun),
gate(NULL)
{
}
~FakeNative();
ke::AString name;
IPluginContext *ctx;
IPluginFunction *call;
SPVM_NATIVE_FUNC gate;
};
struct NativeEntry
{
NativeEntry(CNativeOwner *owner, const sp_nativeinfo_t *native)
: owner(owner),
native(native),
fake(NULL)
{
}
NativeEntry(CNativeOwner *owner, FakeNative *fake)
: owner(owner),
native(NULL),
fake(fake)
{
}
CNativeOwner *owner;
SPVM_NATIVE_FUNC func;
const char *name;
FakeNative *fake;
const sp_nativeinfo_t *native;
ke::AutoPtr<FakeNative> fake;
SPVM_NATIVE_FUNC func() const
{
if (native)
return native->func;
if (fake)
return fake->gate;
return NULL;
}
const char *name() const
{
if (native)
return native->name;
if (fake)
return fake->name.chars();
return NULL;
}
static inline bool matches(const char *name, const NativeEntry *entry)
{
return strcmp(name, entry->name) == 0;
return strcmp(name, entry->name()) == 0;
}
};