From 1497dccd63a84b7ee2b229b1ad9c5c02718f2a78 Mon Sep 17 00:00:00 2001 From: chai Date: Tue, 19 Mar 2019 23:06:27 +0800 Subject: *rename --- source/3rd-party/Luax/luax_class.hpp | 176 +++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100644 source/3rd-party/Luax/luax_class.hpp (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 new file mode 100644 index 0000000..ea1fab9 --- /dev/null +++ b/source/3rd-party/Luax/luax_class.hpp @@ -0,0 +1,176 @@ +#ifndef __LUAX_CLASS_H__ +#define __LUAX_CLASS_H__ + +#include + +#include "luax_config.h" +#include "luax_ref.h" +#include "luax_memberref.h" +#include "luax_cfunctions.h" + +namespace Luax +{ + +#define LUAX_DECL_METHOD(mtd) static int mtd(lua_State* L) + + /// + /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table + /// LuaxGetFactoryName 获得工厂的类名,同时用来避免注册时错误注册为了singleton,通过编译时报错避免 + /// +#define LUAX_DECL_FACTORY(type) \ + 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; }; + + /// + /// RegisterLuaxClass 注册类的方法和成员,比如枚举、常量等到class table + /// LuaxGetSingletonName 获得单例的类名 + /// +#define LUAX_DECL_SINGLETON(type) \ + 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; }; + +#define LUAX_IMPL_METHOD(type, f) int type::f(lua_State* L) + +#define LUAX_REGISTRY(type) void type::RegisterLuaxClass(Luax::LuaxState& state) + +#define LUAX_POSTPROCESS(type) void type::RegisterLuaxPostprocess(Luax::LuaxState& state) + +#define LUAX_REGISTER_FACTORY(stt, type) stt.RegisterFactory() + +#define LUAX_REGISTER_SINGLETON(stt, type) stt.RegisterSingleton() + + /// + /// 需要暴露给lua的native class需要继承此类。通过lua管理的实例要确保引用计数的正确性,在多个线程中需要确定不会误释放。 + /// + template + class LuaxNativeClass + { + public: + + /// + /// 将userdata作为key,在ref table里对userdata添加一个引用,以维持userdata的生命周期。 + /// + template void LuaRetain(LuaxState& state, U* userdata); + + /// + /// 对userdata减少一个引用在ref table里,以尝试回收userdata。 + /// + template void LuaRelease(LuaxState& state, U* userdata); + + protected: + + LuaxNativeClass(); + virtual ~LuaxNativeClass(); + + /// + /// 将userdata push到栈顶,如果没有初始化mUserdata,初始化设置好元表并把初始化好的userdata留在栈顶。并添加一个引用。 + /// + bool PushLuaxUserdata(LuaxState& state); + bool PushLuaxMemberTable(LuaxState& state); + bool PushLuaxRefTable(LuaxState& state); + + /// + /// 成员引用管理,在实例的ref table里。设置、取、清除 + /// + void SetMemberRef(LuaxState& state, LuaxMemberRef& memRef, int idx); + bool PushMemberRef(LuaxState& state, LuaxMemberRef& memRef); + void ClearMemberRef(LuaxState& state, LuaxMemberRef& memRef); + + private: + + friend class LuaxState; + + static void RegisterLuaxClass(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); + + //------------------------------------------------------------------------------------------------------------ + + /// + /// 所有LuaxNativeClass类型的实例共享的内容 + /// + static LuaxStrongRef mClassTable; // class table,工厂和单例都有 + static LuaxStrongRef mSingletonRefTable; // 如果类是单例,这个用来保存singleton的成员,以保证不会被回收类似普通类的 + // ref table。单例的成员是全生命周期的,所以直接在_LUAX_STRONGREF_TABLE + + /// + /// 通过userdata可以拿到: + /// 1: ref table + /// 2: member table + /// 3: class table + /// + LuaxWeakRef mUserdata; + + public: + + //------------------------------------------------------------------------------------------------------------ + // 公共内容 + + LUAX_DECL_METHOD( l___tostring ); + LUAX_DECL_METHOD( l_GetClass ); + LUAX_DECL_METHOD( l_GetClassName ); + + //------------------------------------------------------------------------------------------------------------ + // 工厂类相关 + + LUAX_DECL_METHOD( l___gc ); +#if LUAX_ENABLE_NATIVE_EXTEND + LUAX_DECL_METHOD( l_ExtendFactory ); +#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类 + /// + class LuaxPlainClass + { + public: + + /// + /// 用来注册类的入口函数。可以通过registry(类名)注册类。 + /// + static int registry(lua_State* L); + + LUAX_DECL_METHOD( l___tostring ); + LUAX_DECL_METHOD( l_Extend ); + LUAX_DECL_METHOD( l_New ); + LUAX_DECL_METHOD( l_TypeOf ); + + }; +#endif + +} + +#endif \ No newline at end of file -- cgit v1.1-26-g67d0