diff --git a/core/logic/NativeInvoker.cpp b/core/logic/NativeInvoker.cpp index 304ac1f6..9406c7b8 100644 --- a/core/logic/NativeInvoker.cpp +++ b/core/logic/NativeInvoker.cpp @@ -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; diff --git a/core/logic/NativeOwner.cpp b/core/logic/NativeOwner.cpp index 969e07a9..6bcce341 100644 --- a/core/logic/NativeOwner.cpp +++ b/core/logic/NativeOwner.cpp @@ -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::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); } } diff --git a/core/logic/PluginSys.cpp b/core/logic/PluginSys.cpp index 36778713..c9b865fb 100644 --- a/core/logic/PluginSys.cpp +++ b/core/logic/PluginSys.cpp @@ -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; } diff --git a/core/logic/ShareSys.cpp b/core/logic/ShareSys.cpp index b3446996..768ab148 100644 --- a/core/logic/ShareSys.cpp +++ b/core/logic/ShareSys.cpp @@ -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 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; diff --git a/core/logic/ShareSys.h b/core/logic/ShareSys.h index c5118f23..543200f4 100644 --- a/core/logic/ShareSys.h +++ b/core/logic/ShareSys.h @@ -34,6 +34,8 @@ #include #include +#include +#include #include #include #include @@ -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 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; } };