From e13616b5c40f912853be99f0603f0e4c97b22062 Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 3 Apr 2019 21:56:51 +0800 Subject: *misc --- source/3rd-party/Luax/luax_class.inl | 196 ++++++++++++++++++++++------------- 1 file changed, 122 insertions(+), 74 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 45e6552..95965ff 100644 --- a/source/3rd-party/Luax/luax_class.inl +++ b/source/3rd-party/Luax/luax_class.inl @@ -2,17 +2,16 @@ namespace Luax { //--------------------------------------------------------------------------------// - // 接口 /// /// 对不同类型,通过调用GetLuaClassName获得类型名,如果是派生类,GetClassName会被覆盖,指向luax_c_getupvalue。 /// - template - int LuaxNativeClass::l_GetClassName(lua_State* L) + template + int LuaxNativeClass::_GetClassName(lua_State* L) { LUAX_SETUP(L, "*"); - cc8* type = T::GetLuaxClassName(); + cc8* type = TYPE::GetLuaxClassName(); state.Push(type); return 1; } @@ -22,12 +21,12 @@ namespace Luax /// /// 注册工厂和单例共有的类成员 /// - template - void LuaxNativeClass::RegisterLuaxClass(LuaxState& state) + template + void LuaxNativeClass::RegisterLuaxClassShared(LuaxState& state) { luaL_Reg regTable[] = { - { "GetClass", l_GetClass }, - { "GetClassName", l_GetClassName }, + { "GetClass", _GetClass }, + { "GetClassName", _GetClassName }, { NULL, NULL } }; @@ -37,11 +36,11 @@ namespace Luax /// /// 工厂类的成员,注册在class table /// - template - void LuaxNativeClass::RegisterLuaxFactoryClass(LuaxState& state) + template + void LuaxNativeClass::RegisterLuaxFactoryClass(LuaxState& state) { luaL_Reg regTable[] = { - { "GetRefTable", l_GetRefTable }, + { "GetRefTable", _GetRefTable }, { NULL, NULL } }; @@ -51,8 +50,8 @@ namespace Luax /// /// 单例类的成员,注册在class table /// - template - void LuaxNativeClass::RegisterLuaxSingletonClass(LuaxState& state) + template + void LuaxNativeClass::RegisterLuaxSingletonClass(LuaxState& state) { luaL_Reg regTable[] = { { NULL, NULL } @@ -61,33 +60,70 @@ namespace Luax state.RegisterMethods(regTable); } - template - void LuaxNativeClass::PushLuaxClassTable(LuaxState& state) + template + void LuaxNativeClass::PushLuaxClassTable(LuaxState& state) { assert(mClassTable); mClassTable.PushRef(state); } - template - void LuaxNativeClass::SetLuaxClassTableRef(LuaxState& state, int idx) + template + void LuaxNativeClass::SetLuaxClassTableRef(LuaxState& state, int idx) { mClassTable.SetRef(state, idx); } - template - LuaxNativeClass::LuaxNativeClass() + template + LuaxNativeClass::LuaxNativeClass() + : mWatchDog() +#if LUAX_PROFILER + , mSafer(false) +#endif + { + } + + template + LuaxNativeClass::~LuaxNativeClass() + { + } + +#if LUAX_PROFILER + template + void LuaxNativeClass::operator delete(void* pdead, size_t size) + { + if (pdead == nullptr) + return; + // 堆上创建的实例必须使用Release释放。 + LuaxNativeClass* p = static_cast(pdead); + assert(p->mSafer); + ::operator delete(pdead, size); + } +#endif + + template + void LuaxNativeClass::Retain() { + ++mWatchDog.mNativeRef; } - template - LuaxNativeClass::~LuaxNativeClass() + template + void LuaxNativeClass::Release() { + if (mWatchDog.mNativeRef > 0) + --mWatchDog.mNativeRef; + if (mWatchDog) + { +#if LUAX_PROFILER + mSafer = true; +#endif + delete this; + } } - template + template template - void LuaxNativeClass::LuaxRetain(LuaxState& state, U* userdata) + void LuaxNativeClass::LuaxRetain(LuaxState& state, U* userdata) { if (PushLuaxRefTable(state)) { @@ -103,9 +139,9 @@ namespace Luax } } - template + template template - void LuaxNativeClass::LuaxRelease(LuaxState& state, U* userdata) + void LuaxNativeClass::LuaxRelease(LuaxState& state, U* userdata) { if (PushLuaxRefTable(state)) { @@ -139,10 +175,10 @@ namespace Luax } } - template - bool LuaxNativeClass::PushLuaxUserdata(LuaxState& state) + template + bool LuaxNativeClass::PushLuaxUserdata(LuaxState& state) { - assert(!T::IsLuaxClassSingleton()); + assert(!TYPE::IsLuaxClassSingleton()); if (!mUserdata) { BindToLua(state); @@ -151,8 +187,8 @@ namespace Luax return mUserdata.PushRef(state); } - template - bool LuaxNativeClass::PushLuaxMemberTable(LuaxState& state) + template + bool LuaxNativeClass::PushLuaxMemberTable(LuaxState& state) { int top = state.GetTop(); if (this->PushLuaxUserdata(state)) @@ -172,11 +208,11 @@ namespace Luax return false; } - template - bool LuaxNativeClass::PushLuaxRefTable(LuaxState& state) + template + bool LuaxNativeClass::PushLuaxRefTable(LuaxState& state) { // Singleton - if (T::IsLuaxClassSingleton()) + if (TYPE::IsLuaxClassSingleton()) { if (!this->mSingletonRefTable) { lua_newtable(state); @@ -209,19 +245,21 @@ namespace Luax /// member table 保存lua创建的实例的成员 /// class table 所有本类型的实例共有的函数表 /// - template - void LuaxNativeClass::BindToLua(LuaxState& state) + /// BindToLua只会在第一次注册给Lua虚拟机时调用。 + /// + template + void LuaxNativeClass::BindToLua(LuaxState& state) { // 单例不能绑定userdata - assert(!T::IsLuaxClassSingleton()); + assert(!TYPE::IsLuaxClassSingleton()); assert(!mUserdata); /// - /// 创建userdata并留在栈顶,注意地址要转换为T*,直接用this可能会导致多重继承的类丧失多态。 + /// 创建userdata并留在栈顶,注意地址要转换为TYPE*,直接用this可能会导致多重继承的类丧失多态。 /// 如果直接传this进去,在多重继承情况下,是拿不到另一头的虚函数表的。所以这里需要将this /// 转换为整个对象的低地址,这样可以拿到另一个基类的虚函数表,通过另一个基类实现多态。 /// - T* p = static_cast(this); + TYPE* p = static_cast(this); state.PushPtrUserdata(p); lua_newtable(state); // ref table,无法在lua处访问,用来管理C对象的生命周期 @@ -239,10 +277,10 @@ namespace Luax int refTable = top - 2; // ref table 注册 __tostring 和 __gc - lua_pushcfunction(state, _Tostring); + lua_pushcfunction(state, __tostring); lua_setfield(state, refTable, "__tostring"); - lua_pushcfunction(state, _GC); + lua_pushcfunction(state, __gc); lua_setfield(state, refTable, "__gc"); // ref table 的 __index 和 __newindex 设为 member table @@ -260,13 +298,19 @@ namespace Luax // 设置一个userdata的弱引用,方便通过PushLuaUserdata方法返回lua对象 mUserdata.SetRef(state, -1); assert(mUserdata); + + // 增加一个虚拟机引用,在GC时-1 + ++mWatchDog.mVMRef; +#if LUAX_PROFILER + mRefVMs.insert(state.GetVM()); +#endif } /// /// 成员引用管理 /// - template - void LuaxNativeClass::SetLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef, int idx) + template + void LuaxNativeClass::SetLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef, int idx) { ClearLuaxMemberRef(state, memRef); if (!lua_isnil(state, idx)) @@ -281,8 +325,8 @@ namespace Luax } } - template - bool LuaxNativeClass::PushLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef) + template + bool LuaxNativeClass::PushLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef) { if (memRef) { @@ -301,8 +345,8 @@ namespace Luax return false; } - template - bool LuaxNativeClass::PushLuaxMemberRef(LuaxState& state, int refID) + template + bool LuaxNativeClass::PushLuaxMemberRef(LuaxState& state, int refID) { if (PushLuaxRefTable(state)) { @@ -317,8 +361,8 @@ namespace Luax return false; } - template - void LuaxNativeClass::ClearLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef) + template + void LuaxNativeClass::ClearLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef) { if (memRef) { @@ -336,16 +380,20 @@ namespace Luax /// /// 释放工厂创建的实例 /// - template - int LuaxNativeClass::_GC(lua_State* L) + template + int LuaxNativeClass::__gc(lua_State* L) { + LUAX_STATE(L); + TYPE* self = state.GetUserdata(1); + assert(self); + #if LUAX_PROFILER - std::cout << "Luax: GC<" << T::GetLuaxClassName() << ">\n"; + std::cout << "Luax: GC<" << TYPE::GetLuaxClassName() << ">\n"; #endif - LUAX_SETUP(L, "U"); - T* self = state.GetUserdata(1); - delete self; + --self->mWatchDog.mVMRef; + self->LuaxNativeClass::Release(); + return 0; } @@ -353,14 +401,14 @@ namespace Luax /// 输出格式如下: /// 地址 类名 /// - template - int LuaxNativeClass::_Tostring(lua_State* L) + template + int LuaxNativeClass::__tostring(lua_State* L) { // params: // 1: userdata LUAX_STATE(L); - T* self = state.GetUserdata(1); + TYPE* self = state.GetUserdata(1); if (self) { cc8* classname = ""; @@ -373,7 +421,7 @@ namespace Luax } else { - classname = T::GetLuaxClassName(); + classname = TYPE::GetLuaxClassName(); } lua_pushfstring(L, "%s: %p", classname, self); return 1; @@ -386,8 +434,8 @@ namespace Luax /// 派生出子类,在lua里对派生类的成员和行为进行重新设计,但是保证了userdata的统一。Native class的派生提供__init支持,在 /// native实体创建后可以使用__init进行初始化,派生类拥有和基类一样的New参数列表,且native对象是一样的类型。 /// - template - int LuaxNativeClass::l_ExtendFactory(lua_State* L) + template + int LuaxNativeClass::_ExtendFactory(lua_State* L) { // upvalues: // 1: base class @@ -414,13 +462,13 @@ namespace Luax // .Extend() lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, l_ExtendFactory, 1); + lua_pushcclosure(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_pushcclosure(L, _New, 2); lua_setfield(L, -2, "New"); // __base = baseClass @@ -438,8 +486,8 @@ namespace Luax return 1; } - template - int LuaxNativeClass::l_ExtendSingleton(lua_State* L) + template + int LuaxNativeClass::_ExtendSingleton(lua_State* L) { // upvalues: // 1: base class @@ -466,7 +514,7 @@ namespace Luax // .Extend() lua_pushvalue(L, inheritClass); - lua_pushcclosure(L, l_ExtendFactory, 1); + lua_pushcclosure(L, _ExtendFactory, 1); lua_setfield(L, -2, "Extend"); // __base = baseClass @@ -485,8 +533,8 @@ namespace Luax } #endif /*LUAX_ENABLE_NATIVE_EXTEND*/ - template - int LuaxNativeClass::l_GetClass(lua_State* L) + template + int LuaxNativeClass::_GetClass(lua_State* L) { LUAX_STATE(L); if (!mClassTable) @@ -496,19 +544,19 @@ namespace Luax return 1; } - template - int LuaxNativeClass::l_GetRefTable(lua_State* L) + template + int LuaxNativeClass::_GetRefTable(lua_State* L) { LUAX_STATE(L); - T* self = state.GetUserdata(1); + TYPE* self = state.GetUserdata(1); bool success = self->PushLuaxRefTable(state); if (!success) lua_pushnil(L); return 1; } - template - int LuaxNativeClass::l_New(lua_State* L) + template + int LuaxNativeClass::_New(lua_State* L) { LUAX_STATE(L); @@ -580,7 +628,7 @@ namespace Luax return 0; } - template LuaxStrongRef LuaxNativeClass::mClassTable; // class table - template LuaxStrongRef LuaxNativeClass::mSingletonRefTable; // 单例 + template LuaxStrongRef LuaxNativeClass::mClassTable; // class table + template LuaxStrongRef LuaxNativeClass::mSingletonRefTable; // 单例 } \ No newline at end of file -- cgit v1.1-26-g67d0