From 1ab2501db0f9e14f138292880e37120e7a6184de Mon Sep 17 00:00:00 2001 From: chai Date: Sat, 16 Mar 2019 13:03:50 +0800 Subject: *luax --- Source/3rdParty/Lua51/loadlib.c | 2 +- Source/3rdParty/Luax/luax.h | 1 + Source/3rdParty/Luax/luax_class.hpp | 34 ++++--- Source/3rdParty/Luax/luax_class.inl | 161 +++++++++++++++++++++------------- Source/3rdParty/Luax/luax_context.cpp | 19 ++-- Source/3rdParty/Luax/luax_context.h | 8 +- Source/3rdParty/Luax/luax_enum.cpp | 8 +- Source/3rdParty/Luax/luax_memberref.h | 2 +- Source/3rdParty/Luax/luax_ref.h | 4 +- Source/3rdParty/Luax/luax_runtime.cpp | 20 ++--- Source/3rdParty/Luax/luax_runtime.h | 4 +- Source/3rdParty/Luax/luax_state.cpp | 87 ++++++++++++++---- Source/3rdParty/Luax/luax_state.h | 39 ++++++-- Source/3rdParty/Luax/luax_state.inl | 56 ++++++------ 14 files changed, 281 insertions(+), 164 deletions(-) (limited to 'Source/3rdParty') diff --git a/Source/3rdParty/Lua51/loadlib.c b/Source/3rdParty/Lua51/loadlib.c index 6158c53..9455c53 100644 --- a/Source/3rdParty/Lua51/loadlib.c +++ b/Source/3rdParty/Lua51/loadlib.c @@ -654,7 +654,7 @@ LUALIB_API int luaopen_package (lua_State *L) { lua_setfield(L, -2, "config"); /* set field `loaded' */ luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); - lua_setfield(L, -2, "loaded"); + lua_setfield(L, -2, "loaded"); // LUA_REGISTRYINDEX["_LOADED"]设置为package.loaded\LUA_ENVIRONINDEX["loaded"] /* set field `preload' */ lua_newtable(L); lua_setfield(L, -2, "preload"); diff --git a/Source/3rdParty/Luax/luax.h b/Source/3rdParty/Luax/luax.h index ed67bdc..9a6b0b9 100644 --- a/Source/3rdParty/Luax/luax.h +++ b/Source/3rdParty/Luax/luax.h @@ -6,6 +6,7 @@ #include "luax_namespace.h" #include "luax_ref.h" #include "luax_reftable.h" +#include "luax_memberref.h" #include "luax_enum.h" #include "luax_class.hpp" #include "luax_class.inl" diff --git a/Source/3rdParty/Luax/luax_class.hpp b/Source/3rdParty/Luax/luax_class.hpp index 0d3dc5b..a76d501 100644 --- a/Source/3rdParty/Luax/luax_class.hpp +++ b/Source/3rdParty/Luax/luax_class.hpp @@ -53,7 +53,9 @@ namespace Luax /// /// 将userdata push到栈顶,如果没有初始化mUserdata,初始化设置好元表并把初始化好的userdata留在栈顶。并添加一个引用。 /// - bool PushLuaUserdata(LuaxState& state); + bool PushLuaxUserdata(LuaxState& state); + bool PushLuaxMemberTable(LuaxState& state); + bool PushLuaxRefTable(LuaxState& state); private: @@ -62,15 +64,15 @@ namespace Luax static void RegisterLuaxClass(LuaxState& state); static void RegisterLuaxFactoryClass(LuaxState& state); static void RegisterLuaxSingletonClass(LuaxState& state); - static void RegisterLuaxInterface(LuaxState& state); - static void SetInterfaceTableRef(LuaxState& state, int idx); - static void SetClassTableRef(LuaxState& state, int idx); + static void RegisterLuaxInterface(LuaxState& state); - static void PushInterfaceTable(LuaxState& state); - static void PushClassTable(LuaxState& state); - static void PushRefTable(LuaxState& state); + static void SetLuaxInterfaceTableRef(LuaxState& state, int idx); + static void SetLuaxClassTableRef(LuaxState& state, int idx); + static void PushLuaxInterfaceTable(LuaxState& state); + static void PushLuaxClassTable(LuaxState& state); + /// /// 屏蔽取地址运算符,如果需要地址,只能通过在堆上创建实例得到。在栈上和静态区的变量不能取地址。保证引用计数的准确。如 /// 果需要穿引用,使用引用传递而不是传递地址。 @@ -87,12 +89,16 @@ namespace Luax /// /// 所有LuaxClass类型的实例共享的内容 /// - static LuaxStrongRef mInterfaceTable; // interface table - static LuaxStrongRef mClassTable; // class table - static LuaxStrongRef mRefTable; // 单例 - + static LuaxStrongRef mClassTable; // class table,工厂和单例都有 + static LuaxStrongRef mInterfaceTable; // 如果类是工厂,interface table用来保存类实例化的对象的共有方法 + static LuaxStrongRef mSingletonRefTable; // 如果类是单例,这个用来保存singleton的成员,以保证不会被回收类似普通类的 + // ref table。单例的成员是全生命周期的,所以直接在_LUAX_STRONGREF_TABLE + /// - /// 通过userdata可以拿到ref table\member table\interface table + /// 通过userdata可以拿到: + /// 1: ref table + /// 2: member table + /// 3: interface table /// LuaxWeakRef mUserdata; @@ -113,13 +119,13 @@ namespace Luax LUAX_DECL_METHOD( l_GetClassName ); LUAX_DECL_METHOD( l_GetInterfaceTable ); - LUAX_DECL_METHOD( l_ToString ); + LUAX_DECL_METHOD( l___tostring ); //------------------------------------------------------------------------------------------------------------ // 工厂类相关 LUAX_DECL_METHOD( l_ExtendFactory ); - LUAX_DECL_METHOD( l_GC ); + LUAX_DECL_METHOD( l___gc ); //------------------------------------------------------------------------------------------------------------ // 单例类相关 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 diff --git a/Source/3rdParty/Luax/luax_context.cpp b/Source/3rdParty/Luax/luax_context.cpp index c0fb2f5..d41c24f 100644 --- a/Source/3rdParty/Luax/luax_context.cpp +++ b/Source/3rdParty/Luax/luax_context.cpp @@ -3,34 +3,27 @@ namespace Luax { - // 如果调用了此函数,报错。 - int l_Errfunc(lua_State* L) - { - cc8* err = lua_tostring(L, lua_upvalueindex(1)); - return luaL_error(L, err); - } - - Context::Context(lua_State* L) + LuaxContext::LuaxContext(lua_State* L) : state(L) { assert(state); } - Context::~Context() + LuaxContext::~LuaxContext() { } // 初始化context - void Context::Setup() + void LuaxContext::Setup() { SetupRefTables(); } - void Context::SetupRefTables() + void LuaxContext::SetupRefTables() { // strong ref和 weak ref - strongRefTable.Init(state, "LUAX_STRONGREF_TABLE"); - weakRefTable.Init(state, "LUAX_WEAKREF_TABLE", "v"); + strongRefTable.Init(state, "_LUAX_STRONGREF_TABLE"); + weakRefTable.Init(state, "_LUAX_WEAKREF_TABLE", "v"); } } \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_context.h b/Source/3rdParty/Luax/luax_context.h index 5746cf1..01c5937 100644 --- a/Source/3rdParty/Luax/luax_context.h +++ b/Source/3rdParty/Luax/luax_context.h @@ -11,11 +11,11 @@ namespace Luax /// /// 单个lua_state相关的context。是一系列代理的集合,拷贝也没关系,主要是为了节约内存。 /// - class Context + class LuaxContext { public: - Context(lua_State* L); - ~Context(); + LuaxContext(lua_State* L); + ~LuaxContext(); void Setup(); @@ -23,7 +23,7 @@ namespace Luax LuaxRefTable strongRefTable; // strong ref table LuaxRefTable weakRefTable; // weak ref table - size_t objectCount; // 统计所有在此state中创建的实例 + size_t objectCount; // 统计所有在此state中创建的实例 private: diff --git a/Source/3rdParty/Luax/luax_enum.cpp b/Source/3rdParty/Luax/luax_enum.cpp index 1ccc900..a58593a 100644 --- a/Source/3rdParty/Luax/luax_enum.cpp +++ b/Source/3rdParty/Luax/luax_enum.cpp @@ -11,11 +11,11 @@ namespace Luax int l_rmt__index(lua_State* L) { // params: - // 1. enum table - // 2. key + // 1: enum table + // 2: key // upvalues: - // 1. metatable + // 1: metatable int mt = lua_upvalueindex(1); lua_pushvalue(L, 2); @@ -27,7 +27,7 @@ namespace Luax int l_rmt__newindex(lua_State* L) { // upvalue: - // 1. enum table name + // 1: enum table name cc8* name = lua_tostring(L, lua_upvalueindex(1)); diff --git a/Source/3rdParty/Luax/luax_memberref.h b/Source/3rdParty/Luax/luax_memberref.h index baebd06..a7ff1f6 100644 --- a/Source/3rdParty/Luax/luax_memberref.h +++ b/Source/3rdParty/Luax/luax_memberref.h @@ -5,7 +5,7 @@ namespace Luax { /// - /// LuaxClass的成员引用,存在interface table里,保证正确释放,是强引用。 + /// LuaxClass的成员引用,存在ref table里,保证正确释放,是强引用。 /// class LuaxMemberRef { diff --git a/Source/3rdParty/Luax/luax_ref.h b/Source/3rdParty/Luax/luax_ref.h index 7b484e9..b7aabe5 100644 --- a/Source/3rdParty/Luax/luax_ref.h +++ b/Source/3rdParty/Luax/luax_ref.h @@ -38,7 +38,7 @@ namespace Luax }; /// - /// 强引用,在LUA_REGISTRYINDEX["LUAX_STRONGREF_TABLE"]里 + /// 强引用,在LUA_REGISTRYINDEX["_LUAX_STRONGREF_TABLE"]里,保证lua object不会被回收。 /// class LuaxStrongRef: public LuaxRef { @@ -48,7 +48,7 @@ namespace Luax }; /// - /// 弱引用,在LUA_REGISTRYINDEX["LUAX_WEAKREF_TABLE"]里 + /// 弱引用,在LUA_REGISTRYINDEX["_LUAX_WEAKREF_TABLE"]里,不影响lua object的回收,只是作为一个方便取lua object的映射。 /// class LuaxWeakRef : public LuaxRef { diff --git a/Source/3rdParty/Luax/luax_runtime.cpp b/Source/3rdParty/Luax/luax_runtime.cpp index 47b20cb..b45d36a 100644 --- a/Source/3rdParty/Luax/luax_runtime.cpp +++ b/Source/3rdParty/Luax/luax_runtime.cpp @@ -26,9 +26,9 @@ namespace Luax lua_State* L = lua_open(); assert(L); - // 1. 加入 - mContexts.insert(pair(L, Context(L))); - // 2. 初始化context + // 1) 加入 + mContexts.insert(pair(L, LuaxContext(L))); + // 2) 初始化context (*this)[L].Setup(); return L; @@ -36,7 +36,7 @@ namespace Luax void LuaxRuntime::Close(lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); if (it != mContexts.end()) { lua_close(it->second.state); @@ -46,13 +46,13 @@ namespace Luax bool LuaxRuntime::HasLuaxState(lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); return it != mContexts.end(); } LuaxState& LuaxRuntime::GetLuaxState(lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); if (it != mContexts.end()) { return it->second.state; @@ -61,7 +61,7 @@ namespace Luax LuaxRefTable& LuaxRuntime::GetStrongRefTable(lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); if (it != mContexts.end()) { return it->second.strongRefTable; @@ -70,16 +70,16 @@ namespace Luax LuaxRefTable& LuaxRuntime::GetWeaksRefTable(lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); if (it != mContexts.end()) { return it->second.weakRefTable; } } - Context& LuaxRuntime::operator[](lua_State* L) + LuaxContext& LuaxRuntime::operator[](lua_State* L) { - map::iterator it = mContexts.find(L); + map::iterator it = mContexts.find(L); assert(it != mContexts.end()); return it->second; } diff --git a/Source/3rdParty/Luax/luax_runtime.h b/Source/3rdParty/Luax/luax_runtime.h index cb8b66b..1234627 100644 --- a/Source/3rdParty/Luax/luax_runtime.h +++ b/Source/3rdParty/Luax/luax_runtime.h @@ -35,7 +35,7 @@ namespace Luax LuaxRefTable& GetStrongRefTable(lua_State* L); LuaxRefTable& GetWeaksRefTable(lua_State* L); - Context& operator[](lua_State* L); + LuaxContext& operator[](lua_State* L); private: @@ -47,7 +47,7 @@ namespace Luax /// /// 从lua_State handle到context的映射 /// - std::map mContexts; + std::map mContexts; }; diff --git a/Source/3rdParty/Luax/luax_state.cpp b/Source/3rdParty/Luax/luax_state.cpp index 5253a2c..1414591 100644 --- a/Source/3rdParty/Luax/luax_state.cpp +++ b/Source/3rdParty/Luax/luax_state.cpp @@ -27,23 +27,47 @@ namespace Luax luaL_openlibs(mState); } + void LuaxState::PushGlobalNamespace() + { + int top = GetTop(); + + lua_newtable(mState); // pseudo namespace table + int pnt = GetTop(); + + lua_newtable(mState); // metatable + int mt = GetTop(); + + // __index = _G + // __newindex = _G + lua_pushvalue(mState, LUA_GLOBALSINDEX); + lua_pushvalue(mState, LUA_GLOBALSINDEX); + lua_setfield(mState, mt, "__index"); + lua_setfield(mState, mt, "__newindex"); + + lua_setmetatable(mState, pnt); + + // stack: + // -1 pseudo global namespace + } + void LuaxState::PushNamespace(cc8* name) { - bool isG = !lua_istable(mState, -1); - int idx = isG ? LUA_GLOBALSINDEX : -1; - lua_getfield(mState, idx, name); + assert(IsNamespace(-1)); + + int top = GetTop(); + + lua_getfield(mState, -1, name); if (lua_isnil(mState, -1)) { lua_pop(mState, 1); + lua_newtable(mState); - assert(lua_istable(mState, -1)); lua_pushvalue(mState, -1); - int t = isG ? LUA_GLOBALSINDEX : -3; - lua_setfield(mState, t, name); + lua_setfield(mState, top, name); } // stack: - // -1 namespace + // -1 namespace } void LuaxState::PopNamespace() @@ -52,6 +76,11 @@ namespace Luax lua_pop(mState, 1); } + bool LuaxState::IsNamespace(int idx) + { + return lua_istable(mState, idx); + } + void LuaxState::DoString(const std::string& code) { luaL_dostring(mState, code.c_str()); @@ -146,11 +175,6 @@ namespace Luax lua_pop(mState, n); } - void LuaxState::Settop(int idx) - { - lua_settop(mState, idx); - } - bool LuaxState::IsNil(int idx) { return lua_isnil(mState, idx); @@ -191,6 +215,11 @@ namespace Luax return (mState != 0); } + void LuaxState::Settop(int idx) + { + lua_settop(mState, idx); + } + int LuaxState::GetTop() { return lua_gettop(mState); @@ -244,11 +273,6 @@ namespace Luax return false; } - void LuaxState::RegisterMethods(const luaL_Reg *l) - { - luaL_register(mState, 0, l); - } - void LuaxState::GetField(int idx, cc8* name) { lua_getfield(mState, idx, name); @@ -646,4 +670,33 @@ namespace Luax lua_setfield(L, top, name); } + + void LuaxState::RegisterMethods(const luaL_Reg *l) + { + assert(lua_istable(mState, -1)); + // luaL_register第二个参数为空,则向-1位置注册luaL_Reg中这些函数 + luaL_register(mState, 0, l); + } + + void LuaxState::RegisterMethod(cc8* fname, lua_CFunction func) + { + assert(lua_istable(mState, -1)); + lua_pushcfunction(mState, func); + lua_setfield(mState, -1, fname); + } + + void LuaxState::RegisterPreloader(cc8* libname, lua_CFunction preloader) + { + lua_getglobal(mState, "package"); + lua_getfield(mState, -1, "preload"); + lua_pushcfunction(mState, preloader); + lua_setfield(mState, -2, libname); + lua_pop(mState, 2); + } + + void LuaxState::RegisterLib(cc8* libname, const luaL_Reg* l) + { + luaL_register(mState, libname, l); + } + } \ No newline at end of file diff --git a/Source/3rdParty/Luax/luax_state.h b/Source/3rdParty/Luax/luax_state.h index 166ac26..a936ea6 100644 --- a/Source/3rdParty/Luax/luax_state.h +++ b/Source/3rdParty/Luax/luax_state.h @@ -9,7 +9,7 @@ namespace Luax { - class Context; + class LuaxContext; class LuaxEnum; class LuaxStrongRef; class LuaxWeakRef; @@ -43,11 +43,14 @@ namespace Luax //------------------------------------------------------------------------------------------------------------ // 名称空间管理,名称空间就是一个表,_G是最上面的表 + void PushGlobalNamespace(); void PushNamespace(cc8* name); void PopNamespace(); - + bool IsNamespace(int idx); + //------------------------------------------------------------------------------------------------------------ + void SetTop(int top); int GetTop(); bool CheckParams(int idx, cc8* format); int AbsIndex(int idx); @@ -55,11 +58,6 @@ namespace Luax //------------------------------------------------------------------------------------------------------------ - /// - /// 注册C函数,注意后面加一行{0, 0} - /// - void RegisterMethods(const luaL_Reg *l); - void GetField(int idx, cc8* name); void GetField(int idx, int key); std::string GetField(int idx, cc8* key, cc8* value); @@ -126,6 +124,7 @@ namespace Luax void DoFile(const std::string& file); //------------------------------------------------------------------------------------------------------------ + // 注册方法 /// /// 注册工厂,适用于普通类,有New方法 @@ -142,9 +141,33 @@ namespace Luax /// void RegisterEnum(cc8* name, LuaxEnum* enums); + /// + /// 注册C函数,注意后面加一行{0, 0} + /// + void RegisterMethods(const luaL_Reg *l); + + /// + /// 注册单个C函数 + /// + void RegisterMethod(cc8* fname, lua_CFunction func); + + /// + /// 把preloader加到package.preload里,当require"libname"时lua的loader_preload根据libname找到preloader直接加载。 + /// 用来实现需要require的时候才加载,并且加载过一次后package.loaded记录下来,下次不会再加载。通过require会调用这个 + /// preloader。 + /// + void RegisterPreloader(cc8* libname, lua_CFunction preloader); + + /// + /// 根据luaL_Reg建立lib table,并在_G和package.loaded建立对libname的索引,指向lib table。 + /// + void RegisterLib(cc8* libname, const luaL_Reg* l); + + //------------------------------------------------------------------------------------------------------------ + private: - friend class Context; + friend class LuaxContext; LuaxState(lua_State* state); LuaxState(const LuaxState& state); diff --git a/Source/3rdParty/Luax/luax_state.inl b/Source/3rdParty/Luax/luax_state.inl index b5ee5aa..bd7ca9a 100644 --- a/Source/3rdParty/Luax/luax_state.inl +++ b/Source/3rdParty/Luax/luax_state.inl @@ -1,10 +1,10 @@ namespace Luax { - // 针对普通类和单例类有不同的注册过程,通过LuaxState的两个工厂方法Register_实现 - - // 注册工厂,分为注册interface table和class table,以type name为键设置在名称空间上。在注册阶段不会设置元表,等到New方法调用的时候才会。 - + /// + /// 注册工厂,分为注册interface table和class table,以type name为键设置在名称空间上。在注册阶段不会设置元表,等到New方 + /// 法调用的时候才会。 + /// template void LuaxState::RegisterFactory() { @@ -12,56 +12,51 @@ namespace Luax LuaxState& state = *this; int top = lua_gettop(L); // namespace table - assert(lua_istable(L, top)); - const char* type = T::GetLuaxFactoryName(); - - // interface table + // 1) interface table lua_newtable(L); + LuaxClass::RegisterLuaxInterface(state); + T::RegisterLuaxInterface(state); // interface table[__index] = interface table lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); - LuaxClass::RegisterLuaxInterface(state); - T::RegisterLuaxInterface(state); - - LuaxClass::SetInterfaceTableRef(state, -1); + LuaxClass::SetLuaxInterfaceTableRef(state, -1); lua_settop(L, top); - // class table + // 2) class table lua_newtable(L); - LuaxClass::RegisterLuaxClass(state); LuaxClass::RegisterLuaxFactoryClass(state); T::RegisterLuaxClass(state); // 检测T里面是否没有注册必须的方法 -#define _assertmethod(I, NAME) \ - GetField(I, NAME); \ - assert(IsType(-1, LUA_TFUNCTION)); \ - Pop(); + #define _assertmethod(I, NAME) \ + GetField(I, NAME); \ + assert(IsType(-1, LUA_TFUNCTION)); \ + Pop(); - // New方法可以没有,如果没有的话表示这是一个抽象类 - //_assertmethod(-1, "New"); + _assertmethod(-1, "New"); -#undef _assertmethod + #undef _assertmethod // .Extend() lua_pushvalue(state, -1); // class table - LuaxClass::PushInterfaceTable(state); // interface table + LuaxClass::PushLuaxInterfaceTable(state); // interface table lua_pushcclosure(state, LuaxClass::l_ExtendFactory, 2); lua_setfield(state, -2, "Extend"); // .GetInterfaceTable() - LuaxClass::PushInterfaceTable(state); // interface table + LuaxClass::PushLuaxInterfaceTable(state); // interface table lua_pushcclosure(state, LuaxClass::l_GetInterfaceTable, 1); lua_setfield(state, -2, "GetInterfaceTable"); - LuaxClass::SetClassTableRef(state, -1); + LuaxClass::SetLuaxClassTableRef(state, -1); + const char* type = T::GetLuaxFactoryName(); SetField(top, type); // reset top @@ -71,7 +66,9 @@ namespace Luax T::RegisterLuaxPostprocess(state); } - // 注册单例 + /// + /// Singleton只有一个class table,没有interface table。 + /// template void LuaxState::RegisterSingleton() { @@ -85,11 +82,18 @@ namespace Luax // class table. lua_newtable(L); - LuaxClass::RegisterLuaxClass(state); LuaxClass::RegisterLuaxFactoryClass(state); T::RegisterLuaxClass(state); + LuaxClass::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"); + SetField(top, type); // reset top -- cgit v1.1-26-g67d0