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) if (!entry)
return false; return false;
if (!entry->owner || !entry->func) if (!entry->owner || !entry->func())
return false; return false;
native_ = entry->func; native_ = entry->func();
context_ = pContext; context_ = pContext;
m_curparam = 0; m_curparam = 0;

View File

@ -97,7 +97,7 @@ void CNativeOwner::UnbindWeakRef(const WeakNative & ref)
*/ */
else 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(); List<NativeEntry *>::iterator ntv_iter = m_Natives.begin();
while (ntv_iter != m_Natives.end()) 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); ntv_iter = m_Natives.erase(ntv_iter);
} }
} }

View File

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

View File

@ -309,7 +309,7 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, NativeEntry *pEntry)
pContext = pPlugin->GetBaseContext(); pContext = pPlugin->GetBaseContext();
if (pContext->FindNativeByName(pEntry->name, &i) != SP_ERROR_NONE) if (pContext->FindNativeByName(pEntry->name(), &i) != SP_ERROR_NONE)
{ {
return; return;
} }
@ -336,7 +336,7 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin,
native->user = pEntry; native->user = pEntry;
/* Perform a bind. */ /* Perform a bind. */
native->pfn = pEntry->func; 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)
@ -379,90 +379,63 @@ NativeEntry *ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_native
if ((pEntry = FindNative(ntv->name)) == NULL) if ((pEntry = FindNative(ntv->name)) == NULL)
{ {
pEntry = new NativeEntry; pEntry = new NativeEntry(pOwner, ntv);
pEntry->owner = pOwner;
pEntry->name = ntv->name;
pEntry->func = ntv->func;
pEntry->fake = NULL;
m_NtvCache.insert(ntv->name, pEntry); m_NtvCache.insert(ntv->name, pEntry);
return pEntry; return pEntry;
} }
if (pEntry->owner != NULL) if (pEntry->owner != NULL)
{
return NULL; return NULL;
}
pEntry->owner = pOwner; pEntry->owner = pOwner;
pEntry->func = ntv->func; pEntry->native = NULL;
pEntry->name = ntv->name;
return pEntry; return pEntry;
} }
FakeNative::~FakeNative()
{
g_pSourcePawn2->DestroyFakeNative(gate);
}
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name) void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
{ {
NativeEntry *pEntry; NativeEntry *pEntry;
if ((pEntry = FindNative(name)) == NULL) if ((pEntry = FindNative(name)) == NULL)
{
return; return;
}
if (pEntry->owner != pOwner) if (pEntry->owner != pOwner)
{
return; return;
}
if (pEntry->fake != NULL) pEntry->fake = NULL;
{ pEntry->native = NULL;
g_pSourcePawn2->DestroyFakeNative(pEntry->func);
delete pEntry->fake;
pEntry->fake = NULL;
}
pEntry->func = NULL;
pEntry->name = NULL;
pEntry->owner = NULL; pEntry->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)
{ {
FakeNative *pFake;
NativeEntry *pEntry; NativeEntry *pEntry;
SPVM_NATIVE_FUNC gate;
if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL) if ((pEntry = FindNative(name)) != NULL && pEntry->owner != NULL)
{
return NULL; return NULL;
}
pFake = new FakeNative; ke::AutoPtr<FakeNative> fake(new FakeNative(name, pFunc));
if ((gate = g_pSourcePawn2->CreateFakeNative(func, pFake)) == NULL) fake->gate = g_pSourcePawn2->CreateFakeNative(func, fake);
{ if (!fake->gate)
delete pFake;
return NULL; 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); 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; return pEntry;
} }
@ -527,7 +500,7 @@ FeatureStatus ShareSystem::TestNative(IPluginRuntime *pRuntime, const char *name
if (!entry) if (!entry)
return FeatureStatus_Unknown; return FeatureStatus_Unknown;
if (entry->owner && entry->func) if (entry->owner)
return FeatureStatus_Available; return FeatureStatus_Available;
return FeatureStatus_Unavailable; return FeatureStatus_Unavailable;

View File

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