summaryrefslogtreecommitdiff
path: root/Runtime/Lua/LuaBind/LuaBindState.h
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Lua/LuaBind/LuaBindState.h')
-rw-r--r--Runtime/Lua/LuaBind/LuaBindState.h266
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