summaryrefslogtreecommitdiff
path: root/source/external/Luax/luax_state.h
blob: e162965373bd18f9308b79bc3a18c681170a8efc (plain)
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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
#ifndef __LUAX_STATE_H__
#define __LUAX_STATE_H__

#include <string>

#include "luax_config.h"
#include "luax_reftable.h"
#include "luax_globalstate.h"

namespace Luax 
{

	class LuaxVM;
	class LuaxEnum;
	class LuaxStrongRef;
	class LuaxWeakRef;

	///
	/// lua_StateĴ˱һlua_Stateòݡһʵmetatable£
	///     class table
	///     member table
	///     ref table
	///     userdata
	/// userdataͨgetmetatableȡϼmetatable֮⻹һclass tableעڶӦ
	/// ƿռ
	///
	LUAX_API class LuaxState 
	{
	public:

		LuaxState(lua_State* state);
		LuaxState(const LuaxState& state);
		virtual ~LuaxState();

		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();

		LuaxVM* 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ʼnpushջ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, LuaxEnum* enums);

		///
		/// עCעһ{0 0}
		///
		void RegisterMethods(const luaL_Reg *l);

		///
		/// עᵥC
		///
		void RegisterMethod(cc8* fname, lua_CFunction func);

		///
		/// preloaderӵpackage.preloadrequire"libname"ʱlualoader_preload
		/// libnameҵpreloaderֱӼءʵҪrequireʱżأҼعһκ
		/// package.loaded¼´βټءͨrequirepreloader
		///
		void RegisterPreloader(cc8* libname, lua_CFunction preloader);

		///
		/// luaL_Reglib table_Gpackage.loadedlibnameָlib table
		///
		void RegisterLib(cc8* libname, const luaL_Reg* l);

#if LUAX_ENABLE_PLAIN_CLASS
		///
		/// עᴿluaעắluaࡣ
		///
		void RegisterPlainClassRegistry(cc8* name);
#endif

#if LUAX_ENABLE_PLAIN_ENUM
		///
		/// עᴿluaö٣Էֹ޸öֵ
		///
		void RegisterPlainEnumRegistry(cc8* name);
#endif

	protected:

		friend class LuaxVM;

		///
		/// ζLuaxStateĵַز
		///
		void* operator &();
		void* operator new(size_t size);

		lua_State* const mState;
	};

	//--------------------------------------------------------------------------------//
	// GetValue()ģػ

	template <> bool LuaxState::GetValue < bool >(int idx, const bool value);
	template <> cc8* LuaxState::GetValue < cc8* >(int idx, const cc8* value);
	template <> double LuaxState::GetValue < double >(int idx, const double value);
	template <> float LuaxState::GetValue < float >(int idx, const float value);
	template <> s8 LuaxState::GetValue < s8 >(int idx, const s8 value);
	template <> s16 LuaxState::GetValue < s16 >(int idx, const s16 value);
	template <> s32 LuaxState::GetValue < s32 >(int idx, const s32 value);
	template <> s64 LuaxState::GetValue < s64 >(int idx, const s64 value);
	template <> u8 LuaxState::GetValue < u8 >(int idx, const u8 value);
	template <> u16 LuaxState::GetValue < u16 >(int idx, const u16 value);
	template <> u32 LuaxState::GetValue < u32 >(int idx, const u32 value);
	template <> u64	 LuaxState::GetValue < u64 >(int idx, const u64 value);
	template <> std::string LuaxState::GetValue < std::string >(int idx, const std::string value);
	template <> const void* LuaxState::GetValue < const void* >(int idx, const void* value);

	//--------------------------------------------------------------------------------//
	// CheckValueģػ

	template <> bool LuaxState::CheckValue < bool >(int idx);
	template <> cc8* LuaxState::CheckValue < cc8* >(int idx);
	template <> double LuaxState::CheckValue < double >(int idx);
	template <> float LuaxState::CheckValue < float >(int idx);
	template <> s8 LuaxState::CheckValue < s8 >(int idx);
	template <> s16 LuaxState::CheckValue < s16 >(int idx);
	template <> s32 LuaxState::CheckValue < s32 >(int idx);
	template <> s64 LuaxState::CheckValue < s64 >(int idx);
	template <> u8 LuaxState::CheckValue < u8 >(int idx);
	template <> u16 LuaxState::CheckValue < u16 >(int idx);
	template <> u32 LuaxState::CheckValue < u32 >(int idx);
	template <> u64	 LuaxState::CheckValue < u64 >(int idx);
	template <> std::string LuaxState::CheckValue < std::string >(int idx);
	template <> const void* LuaxState::CheckValue < const void* >(int idx);

	///
	/// ڳԱﴴLuaxStateԲм顣
	///
#define LUAX_SETUP(L, params) \
	Luax::LuaxState state(L); \
	if(!state.CheckParams(1, params)) return 0

#define LUAX_STATE(L) \
	Luax::LuaxState state(L)

	//--------------------------------------------------------------------------------//

	///
	/// ȷȫluaܹڵ֮󷵻صstack״̬
	///
	class LuaxScopedState
		: public LuaxState
	{
	public:
		LuaxScopedState(lua_State* state)
			: LuaxState(state)
		{
			mRestoreTop = lua_gettop(mState);
		}
		LuaxScopedState(const LuaxState& state)
			: LuaxState(state)
		{
			mRestoreTop = lua_gettop(mState);
		}
		~LuaxScopedState()
		{
			if (mState) {
				if (lua_gettop(mState) != mRestoreTop) {
					lua_settop(mState, mRestoreTop);
				}
			}
		}
	private: 
		void* operator new(size_t);
		int mRestoreTop;

	};

}

#endif