1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
|
#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;
typedef void (*ErrorHandler) (cc8 * msg);
// 对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, ErrorHandler handler = NULL);
//------------------------------------------------------------------------------//
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, ErrorHandler handler = NULL);
void LoadFile(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
|