diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/3rdParty/Luax/luax_class.cpp | 33 | ||||
-rw-r--r-- | Source/3rdParty/Luax/luax_class.hpp | 15 | ||||
-rw-r--r-- | Source/3rdParty/Luax/luax_class.inl | 184 | ||||
-rw-r--r-- | Source/3rdParty/Luax/luax_state.cpp | 7 | ||||
-rw-r--r-- | Source/3rdParty/Luax/luax_state.h | 7 | ||||
-rw-r--r-- | Source/3rdParty/Luax/luax_state.inl | 11 | ||||
-rw-r--r-- | Source/Asura.Engine/Application.h | 4 | ||||
-rw-r--r-- | Source/Asura.Engine/application.h | 4 | ||||
-rw-r--r-- | Source/Asura.Engine/scripting/portable.hpp | 3 | ||||
-rw-r--r-- | Source/Samples/LuaxTest/script.lua | 22 |
10 files changed, 259 insertions, 31 deletions
diff --git a/Source/3rdParty/Luax/luax_class.cpp b/Source/3rdParty/Luax/luax_class.cpp index 8c94248..155fd28 100644 --- a/Source/3rdParty/Luax/luax_class.cpp +++ b/Source/3rdParty/Luax/luax_class.cpp @@ -39,6 +39,30 @@ namespace Luax lua_pushvalue(L, -1); // class table lua_setfield(L, -2, "__index"); + lua_pushstring(L, type); + lua_pushcclosure(L, l___tostring, 1); + lua_setfield(L, -2, "__tostring"); + + return 1; + } + + int LuaxPlainClass::l___tostring(lua_State* L) + { + // upvalues: + // 1: class name + + // params: + // 1: instance + + if (!lua_istable(L, 1)) + { + return luaL_typerror(L, 1, lua_typename(L, LUA_TTABLE)); + } + + cc8* type = lua_tostring(L, lua_upvalueindex(1)); + + lua_pushfstring(L, "%s: %p", type, lua_topointer(L, 1)); + return 1; } @@ -64,8 +88,9 @@ namespace Luax lua_pushvalue(L, classTable); lua_setmetatable(L, -2); + // ҵ캯ᴥmetatable.__index,ݼ̳ҡ lua_getfield(L, classTable, "Ctor"); - if (!lua_isnil(L, -1)) + if (state.IsType(-1, LUA_TFUNCTION)) { // stack: // -1: Ctor() @@ -145,13 +170,17 @@ namespace Luax lua_pushcclosure(L, l_Extend, 1); lua_setfield(L, -2, "Extend"); - // .base + // .__base lua_pushvalue(L, baseClass); // base class lua_setfield(L, -2, "__base"); lua_pushvalue(L, -1); // class table lua_setfield(L, -2, "__index"); + lua_pushstring(L, type); + lua_pushcclosure(L, l___tostring, 1); + lua_setfield(L, -2, "__tostring"); + // classmetatableΪbaseClass lua_pushvalue(L, baseClass); lua_setmetatable(L, -2); diff --git a/Source/3rdParty/Luax/luax_class.hpp b/Source/3rdParty/Luax/luax_class.hpp index c196024..1689e0c 100644 --- a/Source/3rdParty/Luax/luax_class.hpp +++ b/Source/3rdParty/Luax/luax_class.hpp @@ -6,6 +6,7 @@ #include "luax_config.h" #include "luax_ref.h" #include "luax_memberref.h" +#include "luax_cfunctions.h" namespace Luax { @@ -117,15 +118,16 @@ namespace Luax // LUAX_DECL_METHOD( l___tostring ); + LUAX_DECL_METHOD( l_GetClass ); LUAX_DECL_METHOD( l_GetClassName ); //------------------------------------------------------------------------------------------------------------ // - LUAX_DECL_METHOD( l___gc ); - LUAX_DECL_METHOD( l_ExtendFactory ); - LUAX_DECL_METHOD( l_GetClass ); - LUAX_DECL_METHOD( l_GetRefTable ); + LUAX_DECL_METHOD( l___gc ); + LUAX_DECL_METHOD( l_ExtendFactory ); + LUAX_DECL_METHOD( l_GetRefTable ); + LUAX_DECL_METHOD( l_New ); //------------------------------------------------------------------------------------------------------------ // @@ -148,8 +150,9 @@ namespace Luax /// static int registry(lua_State* L); - LUAX_DECL_METHOD( l_Extend ); - LUAX_DECL_METHOD( l_New ); + LUAX_DECL_METHOD( l___tostring ); + LUAX_DECL_METHOD( l_Extend ); + LUAX_DECL_METHOD( l_New ); }; 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; // diff --git a/Source/3rdParty/Luax/luax_state.cpp b/Source/3rdParty/Luax/luax_state.cpp index 94ca148..b27825e 100644 --- a/Source/3rdParty/Luax/luax_state.cpp +++ b/Source/3rdParty/Luax/luax_state.cpp @@ -171,6 +171,13 @@ namespace Luax lua_pushlightuserdata(mState, (void*)value); } + void LuaxState::PushValues(int idx, int n) + { + idx = AbsIndex(idx); + for (int i = idx; i < idx + n; ++i) + lua_pushvalue(mState, i); + } + void LuaxState::Pop(int n /* = 1 */) { lua_pop(mState, n); diff --git a/Source/3rdParty/Luax/luax_state.h b/Source/3rdParty/Luax/luax_state.h index fee9d8a..71e2c5c 100644 --- a/Source/3rdParty/Luax/luax_state.h +++ b/Source/3rdParty/Luax/luax_state.h @@ -100,6 +100,11 @@ namespace Luax void Push(const void* value); /// + /// idxʼnpushջidxᱻȡn + /// + void PushValues(int idx, int n); + + /// /// void** ʽuserdataֵΪptr /// void PushPtrUserData(void* ptr); @@ -108,7 +113,7 @@ namespace Luax void Settop(int idx); - template<typename T> T* GetLuaUserdata(int idx); + template<typename T> T* GetLuaUserdata(int idx = 1); //------------------------------------------------------------------------------------------------------------ diff --git a/Source/3rdParty/Luax/luax_state.inl b/Source/3rdParty/Luax/luax_state.inl index 63245bb..712eb1d 100644 --- a/Source/3rdParty/Luax/luax_state.inl +++ b/Source/3rdParty/Luax/luax_state.inl @@ -26,6 +26,7 @@ namespace Luax Pop(); _assertmethod(-1, "New"); + //_assertmethod(-1, "__gc"); #undef _assertmethod @@ -65,16 +66,18 @@ namespace Luax // class table. lua_newtable(L); LuaxNativeClass<T>::RegisterLuaxClass(state); - LuaxNativeClass<T>::RegisterLuaxFactoryClass(state); + LuaxNativeClass<T>::RegisterLuaxSingletonClass(state); T::RegisterLuaxClass(state); LuaxNativeClass<T>::SetLuaxClassTableRef(state, -1); - // class table__index__newindexָ lua_pushvalue(state, -1); lua_setfield(state, -2, "__index"); - lua_pushvalue(state, -1); - lua_setfield(state, -2, "__newindex"); + + // .Extend() + lua_pushvalue(state, -1); // class table + lua_pushcclosure(state, LuaxNativeClass<T>::l_ExtendSingleton, 1); + lua_setfield(state, -2, "Extend"); cc8* type = T::GetLuaxSingletonName(); SetField(top, type); diff --git a/Source/Asura.Engine/Application.h b/Source/Asura.Engine/Application.h index 08b3bea..a260cf8 100644 --- a/Source/Asura.Engine/Application.h +++ b/Source/Asura.Engine/Application.h @@ -1,8 +1,8 @@ #ifndef __ASURA_ENGINE_APPLICATION_H__ #define __ASURA_ENGINE_APPLICATION_H__ -#include "Scripting/Portable.h" -#include "Config.h" +#include "scripting/portable.hpp" +#include "config.h" namespace AsuraEngine { diff --git a/Source/Asura.Engine/application.h b/Source/Asura.Engine/application.h index 08b3bea..a260cf8 100644 --- a/Source/Asura.Engine/application.h +++ b/Source/Asura.Engine/application.h @@ -1,8 +1,8 @@ #ifndef __ASURA_ENGINE_APPLICATION_H__ #define __ASURA_ENGINE_APPLICATION_H__ -#include "Scripting/Portable.h" -#include "Config.h" +#include "scripting/portable.hpp" +#include "config.h" namespace AsuraEngine { diff --git a/Source/Asura.Engine/scripting/portable.hpp b/Source/Asura.Engine/scripting/portable.hpp index aeb1ed0..df0b878 100644 --- a/Source/Asura.Engine/scripting/portable.hpp +++ b/Source/Asura.Engine/scripting/portable.hpp @@ -10,6 +10,9 @@ namespace AsuraEngine namespace Scripting { + /// + /// luaעnative classҪ̳дࡣ + /// template<typename T> class Portable : public Luax::LuaxNativeClass<T> { diff --git a/Source/Samples/LuaxTest/script.lua b/Source/Samples/LuaxTest/script.lua index df6cbdf..7bf9337 100644 --- a/Source/Samples/LuaxTest/script.lua +++ b/Source/Samples/LuaxTest/script.lua @@ -68,7 +68,7 @@ function main() local Foo = Asura.Class("Foo") Foo.Ctor = function(self, age, name, boy) self.age = age - self.name = boy:GetName() + self.name = name self.boy = boy end Foo.GetAge = function(self) @@ -91,7 +91,7 @@ function main() self.age = age - 1 self.name = boy:GetName() self.boy = boy - self.__base.Ctor(self, age, name, boy) + self.__base.Ctor(self, age, "Wangba", boy) end Coo.GetName = function(self) local name = self.__base.GetName(self) @@ -101,6 +101,8 @@ function main() print(coo2:GetAge()) print(coo2.GetClassName()) print(coo2:GetName()) + print(coo2) + print(coo) ---------------------plain enum test local ERace = Asura.Enum("ERace", { ["White"] = 1, @@ -109,6 +111,22 @@ function main() }) print(ERace.White) print(ERace.Asian) +----------------------native class inherit test + local Boy2 = Asura.SimBoy.Extend("Boy2") + Boy2.Speak = function(self) + return self.__base.GetAge(self) + end + Boy2.Ctor = function(self, age, name) + print("ctor " .. age) + print("ctor " .. name) + end + local boy22 = Boy2.New(12, "Liu") + print(boy22) + print(boy22:Speak()) + +------------------------gc test + local boy = Asura.SimBoy.New(11, "chaichai") + boy = nil end function err(msg) print(msg) |