From 8d8c4ff1664625e7428d0d31cd798d9321680cb2 Mon Sep 17 00:00:00 2001 From: chai Date: Thu, 14 Mar 2019 09:08:07 +0800 Subject: *luax --- Source/3rdParty/Luax/luax_class.inl | 292 ++++++++++++++++++++++++++++-------- 1 file changed, 233 insertions(+), 59 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 fd5c1d9..895152e 100644 --- a/Source/3rdParty/Luax/luax_class.inl +++ b/Source/3rdParty/Luax/luax_class.inl @@ -1,75 +1,249 @@ +namespace Luax +{ -//---------------------------------------------------------------------------------------------------------------- -// 接口 + //---------------------------------------------------------------------------------------------------------------- + // 接口 -/// -/// 对不同类型,通过调用GetLuaClassName获得类型名 -/// -template -int LuaxClass::l_GetClassName(lua_State* L) -{ - LUAX_SETUP(L, "*"); + /// + /// 对不同类型,通过调用GetLuaClassName获得类型名 + /// + template + int LuaxClass::l_GetClassName(lua_State* L) + { + LUAX_SETUP(L, "*"); - cc8* type = T::GetLuaxClassName(); - state.Push(type); - return 1; -} + cc8* type = T::GetLuaxClassName(); + state.Push(type); + return 1; + } -//---------------------------------------------------------------------------------------------------------------- + //---------------------------------------------------------------------------------------------------------------- -/// -/// 注册工厂和单例共有的类成员 -/// -template -void LuaxClass::RegisterLuaxClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - { "GetClassName", l_GetClassName }, - { NULL, NULL } - }; + /// + /// 注册工厂和单例共有的类成员 + /// + template + void LuaxClass::RegisterLuaxClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { "GetClassName", l_GetClassName }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 工厂类的成员,注册在class table -/// -template -void LuaxClass::RegisterLuaxFactoryClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - { NULL, NULL } - }; + /// + /// 工厂类的成员,注册在class table + /// + template + void LuaxClass::RegisterLuaxFactoryClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { "GetInterfaceTable", l_GetInterfaceTable }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 工厂实例的成员,注册在interface table -/// -template -void LuaxClass::RegisterLuaxInterface(LuaxState& state) -{ - luaL_Reg regTable[] = { - { "__gc", l_GC }, - { NULL, NULL } - }; + /// + /// 工厂实例的成员,注册在interface table + /// + template + void LuaxClass::RegisterLuaxInterface(LuaxState& state) + { + luaL_Reg regTable[] = { + { "__gc", l_GC }, + { NULL, NULL } + }; - state.Register(regTable); -} + state.Register(regTable); + } -/// -/// 单例类的成员,注册在class table -/// -template -void LuaxClass::RegisterLuaxSingletonClass(LuaxState& state) -{ - luaL_Reg regTable[] = { - {NULL, NULL} - }; + /// + /// 单例类的成员,注册在class table + /// + template + void LuaxClass::RegisterLuaxSingletonClass(LuaxState& state) + { + luaL_Reg regTable[] = { + { NULL, NULL } + }; + + state.Register(regTable); + } + + template + void LuaxClass::PushInterfaceTable(LuaxState& state) + { + assert(mInterfaceTable); + + mInterfaceTable.PushRef(state); + } + + template + void LuaxClass::PushClassTable(LuaxState& state) + { + assert(mClassTable); + + mClassTable.PushRef(state); + } + + template + void LuaxClass::PushRefTable(LuaxState& state) + { + assert(mRefTable); + + mRefTable.Push(state); + } + + template + void LuaxClass::SetInterfaceTableRef(LuaxState& state, int idx) + { + mInterfaceTable.SetRef(state, idx); + } + + template + void LuaxClass::SetClassTableRef(LuaxState& state, int idx) + { + mClassTable.SetRef(state, idx); + } + + template + LuaxClass::LuaxClass() + : mRC(1) // 构造时默认有一个引用 + , mSafer(false) + { + } + + template + LuaxClass::~LuaxClass() + { + assert(mSafer); + } + + template + void LuaxClass::Retain() + { + ++mRC; + } + + template + void LuaxClass::Release() + { + if (--mRC <= 0) + { + mSafer = true; // 打开析构safer + delete this; + } + } + + template + bool LuaxClass::PushLuaUserdata(LuaxState& state) + { + if (!mUserdata) + { + BindToLua(state); + return true; + } + return mUserdata.PushRef(state); + } + + template + void LuaxClass::BindToLua(LuaxState& state) + { + 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 + } + + // 设置一个userdata的弱引用,方便通过native指针返回lua对象 + mUserdata.SetRef(state, -1); + assert(mUserdata); + + if (T::IsLuaxClassSingleton()) + { + + } + } + + //-------------------------------------------------------------------------------------------------------------- + + /// + /// 释放工厂创建的实例 + /// + template + int LuaxClass::l_GC(lua_State* L) + { + LUAX_SETUP(L, "U"); + + return 0; + } + + template + int LuaxClass::l_ToString(lua_State* L) + { + return 0; + } + + template + int LuaxClass::l_ExtendFactory(lua_State* L) + { + return 0; + } + + template + int LuaxClass::l_GetInterfaceTable(lua_State* L) + { + LUAX_STATE(L); + assert(mInterfaceTable); + mInterfaceTable.PushRef(state); + return 0; + } + + template LuaxStrongRef LuaxClass::mInterfaceTable; // interface table + template LuaxStrongRef LuaxClass::mClassTable; // class table + template LuaxStrongRef LuaxClass::mRefTable; // 单例 - state.Register(regTable); } \ No newline at end of file -- cgit v1.1-26-g67d0