diff options
Diffstat (limited to 'Source/3rdParty/Luax/luax_class.inl')
-rw-r--r-- | Source/3rdParty/Luax/luax_class.inl | 161 |
1 files changed, 99 insertions, 62 deletions
diff --git a/Source/3rdParty/Luax/luax_class.inl b/Source/3rdParty/Luax/luax_class.inl index 2d28d68..8cf0f55 100644 --- a/Source/3rdParty/Luax/luax_class.inl +++ b/Source/3rdParty/Luax/luax_class.inl @@ -56,8 +56,8 @@ namespace Luax void LuaxClass<T>::RegisterLuaxInterface(LuaxState& state) { luaL_Reg regTable[] = { - { "__gc", l_GC }, - { NULL, NULL } + { "__gc", l___gc }, + { NULL, NULL } }; state.RegisterMethods(regTable); @@ -78,7 +78,7 @@ namespace Luax } template<typename T> - void LuaxClass<T>::PushInterfaceTable(LuaxState& state) + void LuaxClass<T>::PushLuaxInterfaceTable(LuaxState& state) { assert(mInterfaceTable); @@ -86,7 +86,7 @@ namespace Luax } template<typename T> - void LuaxClass<T>::PushClassTable(LuaxState& state) + void LuaxClass<T>::PushLuaxClassTable(LuaxState& state) { assert(mClassTable); @@ -94,21 +94,13 @@ namespace Luax } template<typename T> - void LuaxClass<T>::PushRefTable(LuaxState& state) - { - assert(mRefTable); - - mRefTable.Push(state); - } - - template<typename T> - void LuaxClass<T>::SetInterfaceTableRef(LuaxState& state, int idx) + void LuaxClass<T>::SetLuaxInterfaceTableRef(LuaxState& state, int idx) { mInterfaceTable.SetRef(state, idx); } template<typename T> - void LuaxClass<T>::SetClassTableRef(LuaxState& state, int idx) + void LuaxClass<T>::SetLuaxClassTableRef(LuaxState& state, int idx) { mClassTable.SetRef(state, idx); } @@ -143,8 +135,9 @@ namespace Luax } template<typename T> - bool LuaxClass<T>::PushLuaUserdata(LuaxState& state) + bool LuaxClass<T>::PushLuaxUserdata(LuaxState& state) { + assert(!T::IsLuaxClassSingleton()); if (!mUserdata) { BindToLua(state); @@ -154,58 +147,102 @@ namespace Luax } template<typename T> + bool LuaxClass<T>::PushLuaxMemberTable(LuaxState& state) + { + int top = state.GetTop(); + if (this->PushLuaxUserdata(state)) + { + if (lua_getmetatable(state, -1)) // ref table + { + lua_replace(state, -2); + if (lua_getmetatable(state, -1)) // member table + { + lua_replace(state, -2); + return true; + } + } + } + state.SetTop(top); + lua_pushnil(state); + return false; + } + + template<typename T> + bool LuaxClass<T>::PushLuaxRefTable(LuaxState& state) + { + // Singleton + if (T::IsLuaxClassSingleton()) + { + if (!this->mSingletonRefTable) { + lua_newtable(state); + this->mSingletonRefTable.SetRef(state, -1); // strong ref to member table won't be garbage collected + } + else { + this->mSingletonRefTable.PushRef(state); + } + return true; + } + // Factory + else + { + if (this->PushLuaxUserdata(state)) + { + if (lua_getmetatable(state, -1)) + { + lua_replace(state, -2); + return true; + } + } + } + return false; + } + + template<typename T> void LuaxClass<T>::BindToLua(LuaxState& state) { + // ܰuserdata + assert(!T::IsLuaxClassSingleton()); assert(!mUserdata); // userdataջ state.PushPtrUserData(this); - // - if (!T::IsLuaxClassSingleton()) - { - lua_newtable(state); // ref table - lua_newtable(state); // member table - LuaxClass<T>::PushInterfaceTable(state); // interface table - - // stack: - // -1: interface table - // -2: member table - // -3: ref table - // -4: userdata - - int top = state.GetTop(); - int memberTable = top - 1; - int refTable = top - 2; - - // ref table ע __gc__tostring - lua_pushcfunction(state, LuaxClass<T>::l_GC); - lua_setfield(state, refTable, "__gc"); - - lua_pushcfunction(state, LuaxClass<T>::l_ToString); - lua_setfield(state, refTable, "__tostring"); - - // member table Ϊ ref table __index __newindex - lua_pushvalue(state, memberTable); - lua_setfield(state, refTable, "__index"); - - lua_pushvalue(state, memberTable); - lua_setfield(state, refTable, "__newindex"); - - // Ԫ - lua_setmetatable(state, -2); // interface is meta of member - lua_setmetatable(state, -2); // member is meta of ref - lua_setmetatable(state, -2); // ref is meta of userdata - } + lua_newtable(state); // ref tableluaʣC + lua_newtable(state); // member tableluaдĶԱ + PushLuaxInterfaceTable(state); // interface tablemember tableûԱinterface tableҡ - // һuserdataãͨnativeָ뷵lua - mUserdata.SetRef(state, -1); - assert(mUserdata); + // stack: + // -1: interface table + // -2: member table + // -3: ref table + // -4: userdata - if (T::IsLuaxClassSingleton()) - { + int top = state.GetTop(); + int memberTable = top - 1; + int refTable = top - 2; - } + // ref table ע __gc__tostring + lua_pushcfunction(state, l___gc); + lua_setfield(state, refTable, "__gc"); + + lua_pushcfunction(state, l___tostring); + lua_setfield(state, refTable, "__tostring"); + + // member table Ϊ ref table __index __newindex + lua_pushvalue(state, memberTable); + lua_setfield(state, refTable, "__index"); + + lua_pushvalue(state, memberTable); + lua_setfield(state, refTable, "__newindex"); + + // Ԫ + lua_setmetatable(state, -2); // interface is meta of member + lua_setmetatable(state, -2); // member is meta of ref + lua_setmetatable(state, -2); // ref is meta of userdata + + // һuserdataãͨPushLuaUserdatalua + mUserdata.SetRef(state, -1); + assert(mUserdata); } //-------------------------------------------------------------------------------------------------------------- @@ -214,7 +251,7 @@ namespace Luax /// ͷŹʵ /// template<typename T> - int LuaxClass<T>::l_GC(lua_State* L) + int LuaxClass<T>::l___gc(lua_State* L) { LUAX_SETUP(L, "U"); @@ -222,7 +259,7 @@ namespace Luax } template<typename T> - int LuaxClass<T>::l_ToString(lua_State* L) + int LuaxClass<T>::l___tostring(lua_State* L) { return 0; } @@ -242,8 +279,8 @@ namespace Luax return 0; } - template<typename T> LuaxStrongRef LuaxClass<T>::mInterfaceTable; // interface table - template<typename T> LuaxStrongRef LuaxClass<T>::mClassTable; // class table - template<typename T> LuaxStrongRef LuaxClass<T>::mRefTable; // + template<typename T> LuaxStrongRef LuaxClass<T>::mInterfaceTable; // interface table + template<typename T> LuaxStrongRef LuaxClass<T>::mClassTable; // class table + template<typename T> LuaxStrongRef LuaxClass<T>::mSingletonRefTable; // }
\ No newline at end of file |