From 1ab2501db0f9e14f138292880e37120e7a6184de Mon Sep 17 00:00:00 2001 From: chai Date: Sat, 16 Mar 2019 13:03:50 +0800 Subject: *luax --- Source/3rdParty/Luax/luax_class.inl | 161 ++++++++++++++++++++++-------------- 1 file changed, 99 insertions(+), 62 deletions(-) (limited to 'Source/3rdParty/Luax/luax_class.inl') 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::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 - void LuaxClass::PushInterfaceTable(LuaxState& state) + void LuaxClass::PushLuaxInterfaceTable(LuaxState& state) { assert(mInterfaceTable); @@ -86,7 +86,7 @@ namespace Luax } template - void LuaxClass::PushClassTable(LuaxState& state) + void LuaxClass::PushLuaxClassTable(LuaxState& state) { assert(mClassTable); @@ -94,21 +94,13 @@ namespace Luax } template - void LuaxClass::PushRefTable(LuaxState& state) - { - assert(mRefTable); - - mRefTable.Push(state); - } - - template - void LuaxClass::SetInterfaceTableRef(LuaxState& state, int idx) + void LuaxClass::SetLuaxInterfaceTableRef(LuaxState& state, int idx) { mInterfaceTable.SetRef(state, idx); } template - void LuaxClass::SetClassTableRef(LuaxState& state, int idx) + void LuaxClass::SetLuaxClassTableRef(LuaxState& state, int idx) { mClassTable.SetRef(state, idx); } @@ -143,8 +135,9 @@ namespace Luax } template - bool LuaxClass::PushLuaUserdata(LuaxState& state) + bool LuaxClass::PushLuaxUserdata(LuaxState& state) { + assert(!T::IsLuaxClassSingleton()); if (!mUserdata) { BindToLua(state); @@ -153,59 +146,103 @@ namespace Luax return mUserdata.PushRef(state); } + template + bool LuaxClass::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 + bool LuaxClass::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 void LuaxClass::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::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::l_GC); - lua_setfield(state, refTable, "__gc"); - - lua_pushcfunction(state, LuaxClass::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 table,无法在lua处访问,用来管理C对象的生命周期 + lua_newtable(state); // member table,lua中创建的对象成员都保存在这里 + PushLuaxInterfaceTable(state); // interface table,如果member 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的弱引用,方便通过PushLuaUserdata方法返回lua对象 + mUserdata.SetRef(state, -1); + assert(mUserdata); } //-------------------------------------------------------------------------------------------------------------- @@ -214,7 +251,7 @@ namespace Luax /// 释放工厂创建的实例 /// template - int LuaxClass::l_GC(lua_State* L) + int LuaxClass::l___gc(lua_State* L) { LUAX_SETUP(L, "U"); @@ -222,7 +259,7 @@ namespace Luax } template - int LuaxClass::l_ToString(lua_State* L) + int LuaxClass::l___tostring(lua_State* L) { return 0; } @@ -242,8 +279,8 @@ namespace Luax return 0; } - template LuaxStrongRef LuaxClass::mInterfaceTable; // interface table - template LuaxStrongRef LuaxClass::mClassTable; // class table - template LuaxStrongRef LuaxClass::mRefTable; // 单例 + template LuaxStrongRef LuaxClass::mInterfaceTable; // interface table + template LuaxStrongRef LuaxClass::mClassTable; // class table + template LuaxStrongRef LuaxClass::mSingletonRefTable; // 单例 } \ No newline at end of file -- cgit v1.1-26-g67d0