From 157530b8b6e11efc5573d5a0db8987a440197aa1 Mon Sep 17 00:00:00 2001 From: chai Date: Fri, 29 Mar 2019 22:28:40 +0800 Subject: *misc --- source/3rd-party/Luax/luax_class.inl | 44 ++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) (limited to 'source/3rd-party/Luax/luax_class.inl') diff --git a/source/3rd-party/Luax/luax_class.inl b/source/3rd-party/Luax/luax_class.inl index d1c8c4b..45e6552 100644 --- a/source/3rd-party/Luax/luax_class.inl +++ b/source/3rd-party/Luax/luax_class.inl @@ -116,7 +116,12 @@ namespace Luax u32 count = state.GetValue(-1, 0); // get the count (or 0) lua_pop(state, 1); // pop the old count - if (count == 0) return; // nothing to do + // no such reference + if (count == 0) + { + state.Pop(2); // userdata, reftable + return; // nothing to do + } if (count > 1) { lua_pushnumber(state, count - 1); // push the new count @@ -125,7 +130,12 @@ namespace Luax lua_pushnil(state); // maybe cause gc } lua_settable(state, -3); // save it in the table + + state.Pop(1); // reftable + return; } + state.Pop(2); // nil, reftable + return; } } @@ -194,9 +204,10 @@ namespace Luax /// /// 创建userdata,并以此添加ref table,member table和class table。 - /// ref table 是kv强引用table,保存对其他userdata的引用计数(通过userdata作为key,计数为value),以及成员引用 + /// ref table 是kv强引用table,保存对其他userdata的引用计数(通过userdata作为key, + /// 计数为value),以及成员引用 /// member table 保存lua创建的实例的成员 - /// class table 所有本类型的实例共有的函数表 + /// class table 所有本类型的实例共有的函数表 /// template void LuaxNativeClass::BindToLua(LuaxState& state) @@ -205,8 +216,13 @@ namespace Luax assert(!T::IsLuaxClassSingleton()); assert(!mUserdata); - // 创建userdata并留在栈顶,注意地址要转换为T*,直接用this可能会导致多重继承的类丧失多态。 - state.PushPtrUserdata(static_cast(this)); + /// + /// 创建userdata并留在栈顶,注意地址要转换为T*,直接用this可能会导致多重继承的类丧失多态。 + /// 如果直接传this进去,在多重继承情况下,是拿不到另一头的虚函数表的。所以这里需要将this + /// 转换为整个对象的低地址,这样可以拿到另一个基类的虚函数表,通过另一个基类实现多态。 + /// + T* p = static_cast(this); + state.PushPtrUserdata(p); lua_newtable(state); // ref table,无法在lua处访问,用来管理C对象的生命周期 lua_newtable(state); // member table,lua中创建的对象成员都保存在这里 @@ -222,10 +238,13 @@ namespace Luax int memberTable = top - 1; int refTable = top - 2; - // ref table 注册 __tostring - lua_pushcfunction(state, l___tostring); + // ref table 注册 __tostring 和 __gc + lua_pushcfunction(state, _Tostring); lua_setfield(state, refTable, "__tostring"); + lua_pushcfunction(state, _GC); + lua_setfield(state, refTable, "__gc"); + // ref table 的 __index 和 __newindex 设为 member table lua_pushvalue(state, memberTable); lua_setfield(state, refTable, "__index"); @@ -233,9 +252,6 @@ namespace Luax lua_pushvalue(state, memberTable); lua_setfield(state, refTable, "__newindex"); - lua_pushcfunction(state, l___gc); - lua_setfield(state, refTable, "__gc"); - // 设置元表 lua_setmetatable(state, -2); // class is meta of member lua_setmetatable(state, -2); // member is meta of ref @@ -321,8 +337,12 @@ namespace Luax /// 释放工厂创建的实例 /// template - int LuaxNativeClass::l___gc(lua_State* L) + int LuaxNativeClass::_GC(lua_State* L) { +#if LUAX_PROFILER + std::cout << "Luax: GC<" << T::GetLuaxClassName() << ">\n"; +#endif + LUAX_SETUP(L, "U"); T* self = state.GetUserdata(1); delete self; @@ -334,7 +354,7 @@ namespace Luax /// 地址 类名 /// template - int LuaxNativeClass::l___tostring(lua_State* L) + int LuaxNativeClass::_Tostring(lua_State* L) { // params: // 1: userdata -- cgit v1.1-26-g67d0