summaryrefslogtreecommitdiff
path: root/Runtime/Lua/LuaBind/LuaBindRefTable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Lua/LuaBind/LuaBindRefTable.cpp')
-rw-r--r--Runtime/Lua/LuaBind/LuaBindRefTable.cpp120
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