From 45328cbadd8a946c19a77301f218efbf650e2f28 Mon Sep 17 00:00:00 2001 From: chai Date: Mon, 18 Oct 2021 19:56:41 +0800 Subject: *misc --- Runtime/Lua/LuaBind/LuaBindRefTable.cpp | 120 ++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 Runtime/Lua/LuaBind/LuaBindRefTable.cpp (limited to 'Runtime/Lua/LuaBind/LuaBindRefTable.cpp') diff --git a/Runtime/Lua/LuaBind/LuaBindRefTable.cpp b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp new file mode 100644 index 0000000..39ef9ab --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindRefTable.cpp @@ -0,0 +1,120 @@ +#include "LuaBindRefTable.h" +#include "LuaBindState.h" + +namespace LuaBind +{ + + RefTable::RefTable() + : mState(nullptr) + { + } + + RefTable::~RefTable() + { + } + + void RefTable::Init(State& state, cc8* name, cc8* mode) + { + assert(!mState); + assert(name); + + mName = name; + mMode = 0; + for (int i = 0; mode && mode[i]; ++i) + { + if (mode[i] == 'k') mMode |= WEAK_KEY; + else if (mode[i] == 'v') mMode |= WEAK_VALUE; + } + mState = state.GetHandle(); + + state.GetField(LUA_REGISTRYINDEX, name); // register[mName] + if (state.IsNil(-1)) + { + state.Pop(); + + lua_newtable(state); // ref table + int ridx = state.AbsIndex(-1); + lua_newtable(state); // metatable of ref table + int idx = state.AbsIndex(-1); + + // __mode + if (mode) + { + state.Push(mode); + state.SetField(idx, "__mode"); + } + + state.Settop(idx); + lua_setmetatable(state, ridx); + + state.Settop(ridx); + state.SetField(LUA_REGISTRYINDEX, name); + } + else + { + state.Pop(); + } + } + + bool RefTable::IsKeyWeak() + { + assert(mState); + + return mMode & WEAK_KEY; + } + + bool RefTable::IsValueWeak() + { + assert(mState); + + return mMode & WEAK_VALUE; + } + + int RefTable::Ref(State& state, int idx) + { + assert(mState); + + idx = state.AbsIndex(idx); + state.GetField(LUA_REGISTRYINDEX, mName); // ref table + lua_pushvalue(state, idx); // stuff + int refID = luaL_ref(state, -2); + assert(refID != LUA_NOREF); + state.Pop(); + return refID; + } + + void RefTable::Unref(State& state, int refID) + { + assert(mState); + + state.GetField(LUA_REGISTRYINDEX, mName); // ref table + luaL_unref(state, -1, refID); + state.Pop(); + return; + } + + void RefTable::PushRefTable(State& state) + { + assert(mState); + + lua_getfield(state, LUA_REGISTRYINDEX, mName); + } + + void RefTable::PushRef(State& state, int refID) + { + assert(mState); + + lua_getfield(state, LUA_REGISTRYINDEX, mName); + lua_rawgeti(state, -1, refID); + lua_replace(state, -2); + } + + void RefTable::Clear(State& state) + { + assert(mState); + + lua_newtable(state); + state.SetField(LUA_REGISTRYINDEX, mName); + } + +} \ No newline at end of file -- cgit v1.1-26-g67d0