sourcepawn: uplift FakeNative to DynamicNative. (#1338)

This removes calls to CreateFakeNative.
This commit is contained in:
David Anderson 2020-10-02 16:42:31 -07:00 committed by GitHub
parent 589d6df75d
commit e0d9dfb68e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 28 deletions

View File

@ -46,16 +46,14 @@ struct FakeNative
FakeNative(const char *name, IPluginFunction *fun)
: name(name),
ctx(fun->GetParentContext()),
call(fun),
gate(NULL)
call(fun)
{
}
~FakeNative();
std::string name;
IPluginContext *ctx;
IPluginFunction *call;
SPVM_NATIVE_FUNC gate;
ke::RefPtr<INativeCallback> wrapper;
};
struct Native : public ke::Refcounted<Native>
@ -66,10 +64,10 @@ struct Native : public ke::Refcounted<Native>
fake(nullptr)
{
}
Native(CNativeOwner *owner, FakeNative *fake)
Native(CNativeOwner *owner, std::unique_ptr<FakeNative>&& fake)
: owner(owner),
native(nullptr),
fake(fake)
fake(std::move(fake))
{
}
@ -77,12 +75,6 @@ struct Native : public ke::Refcounted<Native>
const sp_nativeinfo_t *native;
std::unique_ptr<FakeNative> fake;
SPVM_NATIVE_FUNC func() const
{
if (native)
return native->func;
return fake->gate;
}
const char *name() const
{
if (native)

View File

@ -364,11 +364,11 @@ void ShareSystem::BindNativeToPlugin(CPlugin *pPlugin, const sp_native_t *native
}
}
pPlugin->GetRuntime()->UpdateNativeBinding(
index,
pEntry->func(),
flags,
nullptr);
auto rt = pPlugin->GetRuntime();
if (pEntry->fake)
rt->UpdateNativeBindingObject(index, pEntry->fake->wrapper, flags, nullptr);
else
rt->UpdateNativeBinding(index, pEntry->native->func, flags, nullptr);
}
AlreadyRefed<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const sp_nativeinfo_t *ntv)
@ -382,11 +382,6 @@ AlreadyRefed<Native> ShareSystem::AddNativeToCache(CNativeOwner *pOwner, const s
return entry.forget();
}
FakeNative::~FakeNative()
{
g_pSourcePawn2->DestroyFakeNative(gate);
}
void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
{
NativeCache::Result r = m_NtvCache.find(name);
@ -403,6 +398,32 @@ void ShareSystem::ClearNativeFromCache(CNativeOwner *pOwner, const char *name)
m_NtvCache.remove(r);
}
class DynamicNative final : public INativeCallback
{
public:
DynamicNative(SPVM_FAKENATIVE_FUNC callback, void* data)
: callback_(callback),
data_(data)
{}
void AddRef() override {
refcount_++;
}
void Release() override {
assert(refcount_ > 0);
if (--refcount_ == 0)
delete this;
}
int Invoke(IPluginContext* ctx, const cell_t* params) override {
return callback_(ctx, params, data_);
}
private:
size_t refcount_ = 0;
SPVM_FAKENATIVE_FUNC callback_;
void* data_;
};
AlreadyRefed<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const char *name, SPVM_FAKENATIVE_FUNC func)
{
RefPtr<Native> entry(FindNative(name));
@ -410,14 +431,11 @@ AlreadyRefed<Native> ShareSystem::AddFakeNative(IPluginFunction *pFunc, const ch
return nullptr;
std::unique_ptr<FakeNative> fake(new FakeNative(name, pFunc));
fake->gate = g_pSourcePawn2->CreateFakeNative(func, fake.get());
if (!fake->gate)
return nullptr;
fake->wrapper = new DynamicNative(func, fake.get());
CNativeOwner *owner = g_PluginSys.GetPluginByCtx(fake->ctx->GetContext());
entry = new Native(owner, fake.release());
entry = new Native(owner, std::move(fake));
m_NtvCache.insert(name, entry);
return entry.forget();

@ -1 +1 @@
Subproject commit 3ec6182c993a7717d81cbc6ab5dfec553de7387f
Subproject commit 3c76ed00a3908868825e04da7e588e7b4595c752