diff options
author | chai <chaifix@163.com> | 2021-10-18 19:56:41 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-18 19:56:41 +0800 |
commit | 45328cbadd8a946c19a77301f218efbf650e2f28 (patch) | |
tree | 8ec4f3a9737b2cbb9744f8347a56783743be2a4c /Runtime/Lua/LuaBind/LuaBindRefTable.cpp | |
parent | b5702ece4c2cf751c252e76fb885a7ec41ccabe8 (diff) |
*misc
Diffstat (limited to 'Runtime/Lua/LuaBind/LuaBindRefTable.cpp')
-rw-r--r-- | Runtime/Lua/LuaBind/LuaBindRefTable.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
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 |