diff options
author | chai <chaifix@163.com> | 2021-10-18 19:56:41 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2021-10-18 19:56:41 +0800 |
commit | 45328cbadd8a946c19a77301f218efbf650e2f28 (patch) | |
tree | 8ec4f3a9737b2cbb9744f8347a56783743be2a4c /Runtime/Lua/LuaBind/LuaBindState.h | |
parent | b5702ece4c2cf751c252e76fb885a7ec41ccabe8 (diff) |
*misc
Diffstat (limited to 'Runtime/Lua/LuaBind/LuaBindState.h')
-rw-r--r-- | Runtime/Lua/LuaBind/LuaBindState.h | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/Runtime/Lua/LuaBind/LuaBindState.h b/Runtime/Lua/LuaBind/LuaBindState.h new file mode 100644 index 0000000..776b23d --- /dev/null +++ b/Runtime/Lua/LuaBind/LuaBindState.h @@ -0,0 +1,266 @@ +#ifndef __LUA_BIND_STATE_H__ +#define __LUA_BIND_STATE_H__ + +#include <string> + +#include "LuaBindConfig.h" +#include "LuaBindRefTable.h" +#include "LuaBindGlobalState.h" + +namespace LuaBind +{ + + class VM; + class Enum; + class StrongRef; + class WeakRef; + + // 对lua_State的代理,除了保存一个lua_State的引用不保存其他内容。一个实例的metatable如下: + // class table + // member table + // ref table + // userdata + // 从userdata通过getmetatable获取上级metatable。除此之外还有一个class table注册在对应 + // 的名称空间里。 + LUA_BIND_API class State + { + public: + + State(lua_State* state); + State(const State& state); + virtual ~State(); + + inline lua_State* operator ->() { return mState; }; + inline lua_State& operator *() { return *mState; }; + inline operator lua_State*() { return mState; } + inline operator bool() { return mState != nullptr; }; + + // 获取绑定的lua_State + inline lua_State* GetHandle() { return mState; }; + + global_State* GetGlobalState(); + + VM* GetVM(); + + //------------------------------------------------------------------------------// + + void OpenLibs(); + + //------------------------------------------------------------------------------// + // 名称空间管理,名称空间就是一个表,_G是最上面的表 + + void PushGlobalNamespace(); + void PushNamespace(cc8* name); + void PopNamespace(); + bool IsNamespace(int idx); + + //------------------------------------------------------------------------------// + + void SetTop(int top); + int GetTop(); + bool CheckParams(int idx, cc8* format); + int AbsIndex(int idx); + void Call(int nArgs, int nResults); + + //------------------------------------------------------------------------------// + + void GetField(int idx, cc8* name); + void GetField(int idx, int key); + std::string GetField(int idx, cc8* key, cc8* value); + std::string GetField(int idx, int key, cc8* value); + std::string GetField(int idx, cc8* key, const std::string& value); + std::string GetField(int idx, int key, const std::string& value); + bool GetFieldWithType(int idx, cc8* name, int type); + bool GetFieldWithType(int idx, int key, int type); + bool GetSubfieldWithType(int idx, cc8* format, int type, ...); + static cc8* GetLuaTypeName(int type); + + void SetField(int idx, cc8* key); + + bool IsNil(int idx); + bool IsNilOrNone(int idx); + bool IsTableOrUserdata(int idx); + bool IsTrueOrNotNil(int idx); + bool IsType(int idx, int type); + bool IsType(int idx, cc8* name, int type); + bool IsValid(); + + bool HasField(int idx, cc8* name); + bool HasField(int idx, int key); + bool HasField(int idx, cc8* name, int type); + bool HasField(int idx, int name, int type); + bool HasKeys(int idx); + + void PushNil(); + void Push(bool value); + void Push(cc8* value); + void Push(double value); + void Push(float value); + void Push(int value); + void Push(u16 value); + void Push(u32 value); + void Push(u64 value); + void Push(s64 value); + void Push(uintptr value); + void Push(lua_CFunction value); + void Push(void* data, size_t size); + void Push(const void* value); + void Push(std::string value); + + // 将idx开始的n个push到栈顶,idx会被取正,n向上生长。 + void PushValues(int idx, int n); + + // 以void** 的形式创建userdata,并将值设置为ptr + void PushPtrUserdata(void* ptr); + + void Pop(int n = 1); + + void Settop(int idx); + + template<typename T> T* GetUserdata(int idx = 1); + + //------------------------------------------------------------------------------// + + int ErrorType(int idx, cc8* hint); + + //------------------------------------------------------------------------------// + + template<typename T> T GetValue(int idx, T default_value); + template<typename T> T GetField(int idx, int key, T value); + template<typename T> T GetField(int idx, cc8* key, T value); + template<typename T> void SetField(int idx, cc8* key, T value); + template<typename T> void SetFieldByIndex(int idx, int key, T value); + + template<typename T> T* CheckUserdata(int idx); + template<typename T> T CheckValue(int idx); + + //------------------------------------------------------------------------------// + + void DoString(const std::string& code); + void DoFile(const std::string& file); + + //------------------------------------------------------------------------------// + // 注册方法 + + // 注册工厂,适用于普通类,有New方法 + template<class TYPE> void RegisterFactory(); + + // 注册单例,没有New方法 + template<class TYPE> void RegisterSingleton(); + + // 注册枚举 + void RegisterEnum(cc8* name, Enum* enums); + + // 注册C函数,注意后面加一行{0, 0} + void RegisterMethods(const luaL_Reg *l); + + // 注册单个C函数 + void RegisterMethod(cc8* fname, lua_CFunction func); + + // 把preloader加到package.preload里,当require"libname"时lua的loader_preload根据 + // libname找到preloader直接加载。用来实现需要require的时候才加载,并且加载过一次后 + // package.loaded记录下来,下次不会再加载。通过require会调用这个preloader。 + void RegisterPreloader(cc8* libname, lua_CFunction preloader); + + // 根据luaL_Reg建立lib table,并在_G和package.loaded建立对libname的索引,指向lib table。 + void RegisterLib(cc8* libname, const luaL_Reg* l); + +#if LUA_BIND_ENABLE_PLAIN_CLASS + // 注册纯lua类的注册函数,用来创建纯lua类。 + void RegisterPlainClassRegistry(cc8* name); +#endif + +#if LUA_BIND_ENABLE_PLAIN_ENUM + // 注册纯lua的枚举,以防止修改枚举值。 + void RegisterPlainEnumRegistry(cc8* name); +#endif + + protected: + + friend class VM; + + // 屏蔽对State的地址相关操作 + void* operator &(); + void* operator new(size_t size); + + lua_State* const mState; + }; + + //--------------------------------------------------------------------------------// + // GetValue()模板特化 + + template <> bool State::GetValue < bool >(int idx, const bool value); + template <> cc8* State::GetValue < cc8* >(int idx, const cc8* value); + template <> double State::GetValue < double >(int idx, const double value); + template <> float State::GetValue < float >(int idx, const float value); + template <> s8 State::GetValue < s8 >(int idx, const s8 value); + template <> s16 State::GetValue < s16 >(int idx, const s16 value); + template <> s32 State::GetValue < s32 >(int idx, const s32 value); + template <> s64 State::GetValue < s64 >(int idx, const s64 value); + template <> u8 State::GetValue < u8 >(int idx, const u8 value); + template <> u16 State::GetValue < u16 >(int idx, const u16 value); + template <> u32 State::GetValue < u32 >(int idx, const u32 value); + template <> u64 State::GetValue < u64 >(int idx, const u64 value); + template <> std::string State::GetValue < std::string >(int idx, const std::string value); + template <> const void* State::GetValue < const void* >(int idx, const void* value); + + //--------------------------------------------------------------------------------// + // CheckValue模板特化 + + template <> bool State::CheckValue < bool >(int idx); + template <> cc8* State::CheckValue < cc8* >(int idx); + template <> double State::CheckValue < double >(int idx); + template <> float State::CheckValue < float >(int idx); + template <> s8 State::CheckValue < s8 >(int idx); + template <> s16 State::CheckValue < s16 >(int idx); + template <> s32 State::CheckValue < s32 >(int idx); + template <> s64 State::CheckValue < s64 >(int idx); + template <> u8 State::CheckValue < u8 >(int idx); + template <> u16 State::CheckValue < u16 >(int idx); + template <> u32 State::CheckValue < u32 >(int idx); + template <> u64 State::CheckValue < u64 >(int idx); + template <> std::string State::CheckValue < std::string >(int idx); + template <> const void* State::CheckValue < const void* >(int idx); + + // 在成员方法里创建State并对参数进行检查。 +#define LUA_BIND_SETUP(L, params) \ + LuaBind::State state(L); \ + if(!state.CheckParams(1, params)) return 0 + +#define LUA_BIND_STATE(L) \ + LuaBind::State state(L) + + //--------------------------------------------------------------------------------// + + // 确保不安全的lua调用能够在调用之后返回到最初stack状态。 + class ScopedState + : public State + { + public: + ScopedState(lua_State* state) + : State(state) + { + mRestoreTop = lua_gettop(mState); + } + ScopedState(const State& state) + : State(state) + { + mRestoreTop = lua_gettop(mState); + } + ~ScopedState() + { + if (mState) { + if (lua_gettop(mState) != mRestoreTop) { + lua_settop(mState, mRestoreTop); + } + } + } + private: + void* operator new(size_t); + int mRestoreTop; + + }; + +} + +#endif
\ No newline at end of file |