summaryrefslogtreecommitdiff
path: root/source/external/Luax/luax_class.hpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-06-06 00:11:18 +0800
committerchai <chaifix@163.com>2019-06-06 00:11:18 +0800
commit88b882ed0b432c6aff2063213e2f793a36dd25f7 (patch)
tree5fe5d5334050e1a1146aa63e61e88aa2f5170727 /source/external/Luax/luax_class.hpp
parentf6c0498c9728a286c13980ed3b60763d02e1b3a0 (diff)
*misc
Diffstat (limited to 'source/external/Luax/luax_class.hpp')
-rw-r--r--source/external/Luax/luax_class.hpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/source/external/Luax/luax_class.hpp b/source/external/Luax/luax_class.hpp
new file mode 100644
index 0000000..c39138d
--- /dev/null
+++ b/source/external/Luax/luax_class.hpp
@@ -0,0 +1,281 @@
+#ifndef __LUAX_CLASS_H__
+#define __LUAX_CLASS_H__
+
+#include "luax_config.h"
+
+#if LUAX_PROFILER
+#include <unordered_set>
+#endif
+
+#include <vector>
+
+#include "luax_ref.h"
+#include "luax_memberref.h"
+#include "luax_cfunctions.h"
+#include "luax_watchdog.h"
+
+namespace Luax
+{
+
+ class LuaxVM;
+
+ ///
+ /// RegisterLuaxClass עķͳԱö١ȵclass table
+ /// LuaxGetFactoryName ùͬʱעʱעΪsingletonͨ
+ /// ʱ
+ ///
+#define LUAX_DECL_FACTORY(type, ...) \
+ friend class Luax::LuaxState; \
+ friend class Luax::LuaxNativeClass<type,##__VA_ARGS__>; \
+ 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; }
+
+ ///
+ /// Ϊij󹤳ʹô˺꣬עһڣעắеãעЩ
+ ///
+ ///
+#define LUAX_DECL_ABSTRACT_FACTORY() \
+ static void RegisterLuaxClass(Luax::LuaxState&);\
+ static void RegisterLuaxPostprocess(Luax::LuaxState&)
+
+ ///
+ /// RegisterLuaxClass עķͳԱö١ȵclass table
+ /// LuaxGetSingletonName õ
+ ///
+#define LUAX_DECL_SINGLETON(type, ...) \
+ friend class Luax::LuaxState; \
+ friend class Luax::LuaxNativeClass<type,##__VA_ARGS__>; \
+ 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_DECL_METHOD(mtd) static int mtd(lua_State* L)
+
+#define LUAX_DECL_ENUM(e, under_line_index)
+
+ ///
+ /// ʵֵĺꡣһL
+ ///
+#define LUAX_IMPL_METHOD(type, f) int type::f(lua_State* L)
+
+ ///
+ /// Ӧóʵֵӿڡһstate
+ ///
+#define LUAX_REGISTRY(type) void type::RegisterLuaxClass(Luax::LuaxState& state)
+#define LUAX_POSTPROCESS(type) void type::RegisterLuaxPostprocess(Luax::LuaxState& state)
+
+ ///
+ /// עĺꡣ֮ǰÿɱ꣬ûluaclastable refûעԡ
+ ///
+#define LUAX_REGISTER_FACTORY(state, param) state.RegisterFactory<param>()
+#define LUAX_REGISTER_SINGLETON(state, param) state.RegisterSingleton<param>()
+#define LUAX_REGISTER_ABSTRACT_FACTORY(state, type) type::RegisterLuaxPostprocess(state)
+#define LUAX_REGISTER_METHODS(state, ...) \
+ do{ \
+ luaL_Reg __m[] = {__VA_ARGS__,{0, 0}}; \
+ state.RegisterMethods(__m); \
+ }while(0)
+#define LUAX_REGISTER_ENUM(state, name, ...) \
+ do{ \
+ Luax::LuaxEnum __e[] = {__VA_ARGS__,{0, 0}}; \
+ state.RegisterEnum(name, __e); \
+ }while(0)
+
+#define LUAX_PREPARE(L, T) \
+ LUAX_STATE(L); \
+ T* self = state.GetUserdata<T>(1);
+
+#define LUAX_INHERIT(state, type) type::RegisterLuaxClass(state)
+
+ ///
+ /// ࣬Ϊʵֶ̬ҪЩӿڵⲿҪ̳д֮࣬оͻ
+ /// öӦʵķע̳дʱʵķʵLuaxNativeClassУʵֻ
+ /// ¶ԡ
+ ///
+ /// Effective C++40ڱʹvirtual base£Ӧþܱз
+ /// ݳԱݳԱʼɵһЩ⡣һ㣬vpbӽӽC#Java
+ /// InterfaceԣIͷʶһӿڡ
+ ///
+ class LuaxObject
+ {
+ public:
+ LuaxObject() {};
+ virtual ~LuaxObject() {};
+
+ ///
+ /// Աùʵref tableáȡ
+ ///
+ 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;
+
+ ///
+ /// LuaxNativeClassʵֺ֡ͷnativeԴ
+ ///
+ virtual void Retain() = 0;
+ virtual void Release() = 0;
+
+ };
+
+ // TODO: ȡҪظɴ
+ //class LuaxNativeClassBase
+ //{
+ //}
+
+ ///
+ /// Ҫ¶luanative classҪ̳дࡣͨluaʵҪȷüȷԣ
+ /// ߳Ҫȷͷš
+ ///
+ template<class TYPE, class BASE = LuaxObject>
+ class LuaxNativeClass : public BASE
+ {
+ public:
+
+ ///
+ /// userdataΪkeyref tableuserdataһãάuserdataڡ
+ /// Ƚmember refʵᱻαͬʵõƵЩʵ壬
+ /// luaƵĵgc⡣
+ ///
+ template<class DATATYPE> void LuaxRetain(LuaxState& state, DATATYPE* userdata);
+
+ ///
+ /// userdataһref tableԳԻuserdata
+ ///
+ template<class DATATYPE> void LuaxRelease(LuaxState& state, DATATYPE* userdata);
+
+ ///
+ /// userdata pushջûгʼmUserdataʼúԪѳʼõ
+ /// userdataջһáһnativeȨƽluaƵķ
+ ///
+ 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 final;
+ void Release() override final;
+
+#if LUAX_PROFILER
+ // Զϴʵdeleteռ
+ static void operator delete(void* pdead, size_t size);
+#endif
+
+ protected:
+
+ LuaxNativeClass();
+ virtual ~LuaxNativeClass();
+
+ ///
+ /// Աùʵref tableáȡ
+ ///
+ void SetLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef, int idx);
+ bool PushLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef);
+ void ClearLuaxMemberRef(LuaxState& state, LuaxMemberRef& memRef);
+
+ private:
+
+ friend class LuaxState;
+
+ 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);
+
+ ///
+ /// userdataʵstate
+ ///
+ void BindToLua(LuaxState& state);
+
+ //------------------------------------------------------------------------------//
+
+ //
+ static int __tostring (lua_State*);
+ static int _GetClass (lua_State*);
+ static int _GetClassName (lua_State*);
+
+ //
+ static int __gc (lua_State*);
+ static int _GetRefTable (lua_State*);
+ static int _New (lua_State*);
+
+#if LUAX_ENABLE_NATIVE_EXTEND
+ static int _ExtendFactory (lua_State*);
+ static int _ExtendSingleton (lua_State*);
+#endif
+
+ //--------------------------------------------------------------------------------//
+
+ ///
+ /// class table͵С
+ ///
+ static LuaxStrongRef mClassTable;
+
+ ///
+ /// ǵsingletonùϵԱ֤ᱻͨref table
+ /// ijԱȫڵģֱ_LUAX_STRONGREF_TABLEuserdata
+ /// LuaxRetain\LuaxReleasemember refʱ͹ʵͬǴref table
+ /// ģtable_LUAX_STRONGREF_TABLE
+ ///
+ static LuaxStrongRef mSingletonRefTable;
+
+ ///
+ /// ͨuserdataõ:
+ /// 1: ref table
+ /// 2: member table
+ /// 3: class table
+ ///
+ LuaxWeakRef mUserdata;
+
+ ///
+ /// ͨɾ
+ ///
+ LuaxWatchDog mWatchDog;
+
+#if LUAX_PROFILER
+ // йܴ˶
+ std::unordered_set<LuaxVM*> mRefVMs;
+ // գ಻ⲿʹdeleteֱɾӦʹRelease
+ bool mSafer;
+#endif
+
+ };
+
+#if LUAX_ENABLE_PLAIN_CLASS
+ ///
+ /// lua
+ ///
+ class LuaxPlainClass
+ {
+ public:
+
+ ///
+ /// עںͨregistry()עࡣ
+ ///
+ static int registry(lua_State* L);
+
+ LUAX_DECL_METHOD(__tostring);
+ LUAX_DECL_METHOD(_Extend);
+ LUAX_DECL_METHOD(_New);
+ LUAX_DECL_METHOD(_TypeOf);
+
+ };
+#endif
+
+}
+
+#endif \ No newline at end of file