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.hpp | 168 ++++++++++++++++++++++------------- 1 file changed, 105 insertions(+), 63 deletions(-) (limited to 'source/3rd-party/Luax/luax_class.hpp') diff --git a/source/3rd-party/Luax/luax_class.hpp b/source/3rd-party/Luax/luax_class.hpp index ba8d16a..c41adbd 100644 --- a/source/3rd-party/Luax/luax_class.hpp +++ b/source/3rd-party/Luax/luax_class.hpp @@ -1,27 +1,36 @@ #ifndef __LUAX_CLASS_H__ #define __LUAX_CLASS_H__ +#include "luax_config.h" + +#if LUAX_PROFILER +#include +#endif + #include -#include "luax_config.h" #include "luax_ref.h" #include "luax_memberref.h" #include "luax_cfunctions.h" +#include "luax_dog.h" namespace Luax { + class LuaxVM; + /// /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table /// LuaxGetFactoryName 获得工厂的类名,同时用来避免注册时错误注册为了singleton,通过编译 /// 时报错避免 /// #define LUAX_DECL_FACTORY(type) \ - static void RegisterLuaxClass(Luax::LuaxState&);\ - static void RegisterLuaxPostprocess(Luax::LuaxState&); \ + friend class Luax::LuaxState; \ + static void RegisterLuaxClass(Luax::LuaxState&); \ + static void RegisterLuaxPostprocess(Luax::LuaxState&); \ static const char* GetLuaxFactoryName() { return #type; };\ static const char* GetLuaxClassName() { return #type; };\ - static bool IsLuaxClassSingleton() { return false; } + static bool IsLuaxClassSingleton() { return false; } /// /// 作为基类的抽象工厂类可以使用此宏,注册一个入口,在派生类的注册函数中调用,注册基类的这些 @@ -30,21 +39,22 @@ namespace Luax #define LUAX_DECL_ABSTRACT_FACTORY() \ static void RegisterLuaxClass(Luax::LuaxState&);\ static void RegisterLuaxPostprocess(Luax::LuaxState&) - + /// /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table /// LuaxGetSingletonName 获得单例的类名 /// #define LUAX_DECL_SINGLETON(type) \ - static void RegisterLuaxClass(Luax::LuaxState&); \ - static void RegisterLuaxPostprocess(Luax::LuaxState&); \ + friend class Luax::LuaxState; \ + static void RegisterLuaxClass(Luax::LuaxState&); \ + static void RegisterLuaxPostprocess(Luax::LuaxState&); \ static const char* GetLuaxSingletonName() { return #type; }; \ static const char* GetLuaxClassName() { return #type; }; \ - static bool IsLuaxClassSingleton() { return true; } - + static bool IsLuaxClassSingleton() { return true; } + #define LUAX_DECL_METHOD(mtd) static int mtd(lua_State* L) -#define LUAX_DECL_ENUM(e, under_line_index) static void _luax_decl_enum_##e() +#define LUAX_DECL_ENUM(e, under_line_index) static void _luax_dec_enum_##e() /// /// 标明方法实现的宏。上下文里有一个L。 @@ -58,10 +68,10 @@ namespace Luax #define LUAX_POSTPROCESS(type) void type::RegisterLuaxPostprocess(Luax::LuaxState& state) /// - /// 用来注册的宏。 + /// 用来注册的宏。之前这里忘了用可变宏,导致没有luaclastable ref没有注册对。 /// -#define LUAX_REGISTER_FACTORY(state, type) state.RegisterFactory() -#define LUAX_REGISTER_SINGLETON(state, type) state.RegisterSingleton() +#define LUAX_REGISTER_FACTORY(state, param) state.RegisterFactory() +#define LUAX_REGISTER_SINGLETON(state, param) state.RegisterSingleton() #define LUAX_REGISTER_ABSTRACT_FACTORY(state, type) type::RegisterLuaxPostprocess(state) #define LUAX_REGISTER_METHODS(state, ...) \ do{ \ @@ -89,56 +99,82 @@ namespace Luax /// 置数据成员,规避数据成员初始化造成的一些隐性问题。依据这一点,vpb基类更加接近C#和Java中 /// 的Interface。所以,在这里把类用I开头标识这是一个接口。 /// - class ILuaxNativeAccessor + class LuaxObject { public: + LuaxObject() {}; + virtual ~LuaxObject() {}; /// - /// 成员引用管理,在实例的ref table里。设置、取、清除 + /// 成员引用管理,在实例的ref table里。设置、取、清除。 /// - virtual bool PushLuaxMemberRef(LuaxState& state, int refID) { assert(false); return false; }; + virtual bool PushLuaxMemberRef(LuaxState& state, int refID) = 0; + virtual bool PushLuaxUserdata(LuaxState& state) = 0; + virtual bool PushLuaxMemberTable(LuaxState& state) = 0; + virtual bool PushLuaxRefTable(LuaxState& state) = 0; - virtual bool PushLuaxUserdata(LuaxState& state) { assert(false); return false; }; - virtual bool PushLuaxMemberTable(LuaxState& state) { assert(false); return false; }; - virtual bool PushLuaxRefTable(LuaxState& state) { assert(false); return false; }; + /// + /// 被LuaxNativeClass实现。 + /// + virtual void Retain() = 0; + virtual void Release() = 0; }; + //class LuaxNativeClassBase + //{ + //} + /// /// 需要暴露给lua的native class需要继承此类。通过lua管理的实例要确保引用计数的正确性,在 /// 多个线程中需要确定不会误释放。 /// - template - class LuaxNativeClass : virtual public ILuaxNativeAccessor + template + class LuaxNativeClass : public BASE { public: - static bool IsTypeOf(ILuaxNativeAccessor); - /// /// 将userdata作为key,在ref table里对userdata添加一个引用,以维持userdata的生命周期。 /// 相比较member ref,这个用在实体会被多次被不同其他实体引用的情况,并频繁销毁这些实体, - ///避免lua频繁的调用gc检测。 + /// 避免lua频繁的调用gc检测。 /// - template void LuaxRetain(LuaxState& state, U* userdata); + template void LuaxRetain(LuaxState& state, USERDATA* userdata); /// /// 对userdata减少一个引用在ref table里,以尝试回收userdata。 /// - template void LuaxRelease(LuaxState& state, U* userdata); - - bool PushLuaxMemberRef(LuaxState& state, int refID) override; + template void LuaxRelease(LuaxState& state, USERDATA* userdata); /// /// 将userdata push到栈顶,如果没有初始化mUserdata,初始化设置好元表并把初始化好的 /// userdata留在栈顶。并添加一个引用。这是一个将native对象所有权移交给lua控制的方法。 /// - bool PushLuaxUserdata(LuaxState& state); - bool PushLuaxMemberTable(LuaxState& state); - bool PushLuaxRefTable(LuaxState& state); + bool PushLuaxMemberRef(LuaxState& state, int refID) override; + bool PushLuaxUserdata(LuaxState& state) override; + bool PushLuaxMemberTable(LuaxState& state) override; + bool PushLuaxRefTable(LuaxState& state) override; + + /// + /// Watch dog 添加一个native引用。luaVM引用不会提供外部接口。继承此类的派生类不能直接使用 + /// delete方法,应该使用Release释放。一般情况下这个操作由虚拟机__gc进行,但是允许用户 + /// 程序在native中隔绝虚拟机情况下释放,这种情况下要使用Release。 + /// + /// 这两个函数是native接口。 + /// + void Retain() override; + void Release() override; + +#if LUAX_PROFILER + // 对堆上创建的实例进行delete保险检查 + static void operator delete(void* pdead, size_t size); +#endif protected: + LuaxNativeClass(); + virtual ~LuaxNativeClass(); + /// /// 成员引用管理,在实例的ref table里。设置、取、清除 /// @@ -146,36 +182,49 @@ namespace Luax bool PushLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef); void ClearLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef); - LuaxNativeClass(); - virtual ~LuaxNativeClass(); - private: friend class LuaxState; - static void RegisterLuaxClass(LuaxState& state); + static void RegisterLuaxClassShared(LuaxState& state); static void RegisterLuaxFactoryClass(LuaxState& state); static void RegisterLuaxSingletonClass(LuaxState& state); static void SetLuaxClassTableRef(LuaxState& state, int idx); - static void PushLuaxClassTable(LuaxState& state); - - /// - /// 屏蔽取地址运算符,如果需要地址,只能通过在堆上创建实例得到。在栈上和静态区的变量不能 - /// 取地址。保证引用计数的准确。如果需要穿引用,使用引用传递而不是传递地址。 - /// - //void* operator &(); /// /// 创建userdata,绑定实例到state。 /// void BindToLua(LuaxState& state); + //------------------------------------------------------------------------------// + + // 公共内容 + LUAX_DECL_METHOD(__tostring); + LUAX_DECL_METHOD(_GetClass); + LUAX_DECL_METHOD(_GetClassName); + + // 工厂类相关 + LUAX_DECL_METHOD(__gc); +#if LUAX_ENABLE_NATIVE_EXTEND + LUAX_DECL_METHOD(_ExtendFactory); +#endif + LUAX_DECL_METHOD(_GetRefTable); + LUAX_DECL_METHOD(_New); + + // 单例类相关 +#if LUAX_ENABLE_NATIVE_EXTEND + LUAX_DECL_METHOD(_ExtendSingleton); +#endif + + //--------------------------------------------------------------------------------// + /// /// class table,工厂和单例都有。 /// static LuaxStrongRef mClassTable; + /// /// 如果类是单例,这个用来保存singleton的引用关系,以保证不会被回收类似普通类的ref table。 /// 单例的成员是全生命周期的,所以直接在_LUAX_STRONGREF_TABLE。单例对userdata进行 @@ -183,7 +232,7 @@ namespace Luax /// 的,这个table在_LUAX_STRONGREF_TABLE里。 /// static LuaxStrongRef mSingletonRefTable; - + /// /// 通过userdata可以拿到: /// 1: ref table @@ -192,27 +241,20 @@ namespace Luax /// LuaxWeakRef mUserdata; - // 公共内容 - LUAX_DECL_METHOD( _Tostring ); - LUAX_DECL_METHOD( l_GetClass ); - LUAX_DECL_METHOD( l_GetClassName ); + /// + /// 通过后才能删除 + /// + LuaxDog mWatchDog; - // 工厂类相关 - LUAX_DECL_METHOD( _GC ); -#if LUAX_ENABLE_NATIVE_EXTEND - LUAX_DECL_METHOD( l_ExtendFactory ); +#if LUAX_PROFILER + // 托管此对象的虚拟机 + std::unordered_set mRefVMs; + // 保险,此类的派生类不能在外部使用delete直接删除,而应该使用Release + bool mSafer; #endif - LUAX_DECL_METHOD( l_GetRefTable ); - LUAX_DECL_METHOD( l_New ); - // 单例类相关 -#if LUAX_ENABLE_NATIVE_EXTEND - LUAX_DECL_METHOD( l_ExtendSingleton ); -#endif }; - //--------------------------------------------------------------------------------// - #if LUAX_ENABLE_PLAIN_CLASS /// /// 纯lua类 @@ -226,10 +268,10 @@ namespace Luax /// static int registry(lua_State* L); - LUAX_DECL_METHOD( _Tostring ); - LUAX_DECL_METHOD( l_Extend ); - LUAX_DECL_METHOD( l_New ); - LUAX_DECL_METHOD( l_TypeOf ); + LUAX_DECL_METHOD(__tostring); + LUAX_DECL_METHOD(_Extend); + LUAX_DECL_METHOD(_New); + LUAX_DECL_METHOD(_TypeOf); }; #endif -- cgit v1.1-26-g67d0