diff options
Diffstat (limited to 'Source/3rdParty/Luax/luax_class.inl')
-rw-r--r-- | Source/3rdParty/Luax/luax_class.inl | 184 |
1 files changed, 172 insertions, 12 deletions
diff --git a/Source/3rdParty/Luax/luax_class.inl b/Source/3rdParty/Luax/luax_class.inl index 666c1a3..48f1c1a 100644 --- a/Source/3rdParty/Luax/luax_class.inl +++ b/Source/3rdParty/Luax/luax_class.inl @@ -26,6 +26,7 @@ namespace Luax void LuaxNativeClass<T>::RegisterLuaxClass(LuaxState& state) { luaL_Reg regTable[] = { + { "GetClass", l_GetClass }, { "GetClassName", l_GetClassName }, { NULL, NULL } }; @@ -40,7 +41,6 @@ namespace Luax void LuaxNativeClass<T>::RegisterLuaxFactoryClass(LuaxState& state) { luaL_Reg regTable[] = { - { "GetClass", l_GetClass }, { "GetRefTable", l_GetRefTable }, { NULL, NULL } }; @@ -222,10 +222,7 @@ namespace Luax int memberTable = top - 1; int refTable = top - 2; - // ref table ע __gc __tostring - lua_pushcfunction(state, l___gc); - lua_setfield(state, refTable, "__gc"); - + // ref table ע __tostring lua_pushcfunction(state, l___tostring); lua_setfield(state, refTable, "__tostring"); @@ -236,6 +233,9 @@ 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 @@ -308,7 +308,8 @@ namespace Luax int LuaxNativeClass<T>::l___gc(lua_State* L) { LUAX_SETUP(L, "U"); - + T* self = state.GetLuaUserdata<T>(1); + delete self; return 0; } @@ -319,12 +320,13 @@ namespace Luax template<typename T> int LuaxNativeClass<T>::l___tostring(lua_State* L) { + // params: + // 1: userdata + LUAX_STATE(L); T* self = state.GetLuaUserdata<T>(1); if (self) { - char buf[1024] = {0}; - const char* fmt = "%p <%s>"; cc8* classname = ""; lua_getfield(state, 1, "GetClassName"); if (state.IsType(-1, LUA_TFUNCTION)) @@ -337,27 +339,112 @@ namespace Luax { classname = T::GetLuaxClassName(); } - sprintf(buf, fmt, self, classname); - lua_pushstring(L, buf); + lua_pushfstring(L, "%s: %p", classname, self); return 1; } return 0; } + /// + /// ࣬luaijԱΪƣDZ֤userdataͳһNative classṩCtor֧֣ + /// nativeʵ崴ʹCtorгʼӵкͻһNewбnativeһ͡ + /// template<typename T> int LuaxNativeClass<T>::l_ExtendFactory(lua_State* L) { + // upvalues: + // 1: base class + // params: + // 1: class name - return 0; + int baseClass = lua_upvalueindex(1); + + lua_newtable(L); // class table + + int inheritClass = lua_gettop(L); + + // .GetClassName() + cc8* type = lua_tostring(L, 1); + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // .GetClass() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // .Extend() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, l_ExtendFactory, 1); + lua_setfield(L, -2, "Extend"); + + // .New() + lua_pushvalue(L, inheritClass); + lua_getfield(L, baseClass, "New"); + lua_pushcclosure(L, l_New, 2); + lua_setfield(L, -2, "New"); + + // __base = baseClass + lua_pushvalue(L, baseClass); + lua_setfield(L, -2, "__base"); + + // __index = inheritClass + lua_pushvalue(L, inheritClass); + lua_setfield(L, -2, "__index"); + + // metatable is baseClass + lua_pushvalue(L, baseClass); + lua_setmetatable(L, inheritClass); + + return 1; } template<typename T> int LuaxNativeClass<T>::l_ExtendSingleton(lua_State* L) { + // upvalues: + // 1: base class + // params: + // 1: class name - return 0; + int baseClass = lua_upvalueindex(1); + + lua_newtable(L); // class name + + int inheritClass = lua_gettop(L); + + // .GetClassName() + cc8* type = lua_tostring(L, 1); + lua_pushstring(L, type); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClassName"); + + // .GetClass() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, luax_c_getupvalue, 1); + lua_setfield(L, -2, "GetClass"); + + // .Extend() + lua_pushvalue(L, inheritClass); + lua_pushcclosure(L, l_ExtendFactory, 1); + lua_setfield(L, -2, "Extend"); + + // __base = baseClass + lua_pushvalue(L, baseClass); + lua_setfield(L, -2, "__base"); + + // __index = inheritClass + lua_pushvalue(L, inheritClass); + lua_setfield(L, -2, "__index"); + + // metatable is baseClass + lua_pushvalue(L, baseClass); + lua_setmetatable(L, inheritClass); + + return 1; } template<typename T> @@ -382,6 +469,79 @@ namespace Luax return 1; } + template<typename T> + int LuaxNativeClass<T>::l_New(lua_State* L) + { + LUAX_STATE(L); + + // upvalues: + // 1: class table + // 2: original New() + + // stack: + // -1~-n: args + + int n = lua_gettop(L); // n args + + lua_pushvalue(L, lua_upvalueindex(2)); + if (state.IsType(-1, LUA_TFUNCTION)) + { + // stack: + // -1: New + // -2~-1-n: args + + state.PushValues(-1 - n, n); + + // stack: + // -1~-n: args + // -n-1: New + // -n-2~-1-2n: args + + state.Call(n, 1); + + // stack: + // -1: userdata + // -2~-1-n: args + + // reset member table's metatable to class table + if (state.IsType(-1, LUA_TUSERDATA)) + { + if (lua_getmetatable(L, -1)) // ref table + { + if (lua_getmetatable(L, -1)) // member table + { + lua_pushvalue(L, lua_upvalueindex(1)); // class table + lua_setmetatable(L, -2); + state.Pop(); // member table + } + state.Pop(); // ref table + } + + // stack: + // -1: userdata + // -2~-1-n: args + + int args = state.AbsIndex(-1 - n); + + // ԵCtor + lua_getfield(L, lua_upvalueindex(1), "Ctor"); + + if (state.IsType(-1, LUA_TFUNCTION)) + { + lua_pushvalue(L, -2); // userdata + state.PushValues(args, n); + state.Call(n + 1, 0); + } + else + state.Pop(); + + } + + return 1; + } + return 0; + } + template<typename T> LuaxStrongRef LuaxNativeClass<T>::mClassTable; // class table template<typename T> LuaxStrongRef LuaxNativeClass<T>::mSingletonRefTable; // |