-
Notifications
You must be signed in to change notification settings - Fork 1
/
SoLuaBind.cpp
executable file
·319 lines (314 loc) · 8.72 KB
/
SoLuaBind.cpp
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
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
//-----------------------------------------------------------------------------
#include "SoLuaBind.h"
#include "SoLuaErrorHandle.h"
//-----------------------------------------------------------------------------
lua_State* SoLuaBind::ms_L = 0;
SoLuaBind::stElement SoLuaBind::ms_kPushElementList[SoLuaBind_MaxCount];
SoLuaBind::stElement SoLuaBind::ms_kPopElementList[SoLuaBind_MaxCount];
int SoLuaBind::ms_nPushSize = 0;
int SoLuaBind::ms_nPopSize = 0;
int SoLuaBind::ms_nBindResultCount = 0;
bool SoLuaBind::ms_bHandleError = false;
//-----------------------------------------------------------------------------
void SoLuaBind::InitLuaBind(lua_State* L)
{
ms_L = L;
}
//-----------------------------------------------------------------------------
void SoLuaBind::ReleaseLuaBind()
{
ms_L = 0;
}
//-----------------------------------------------------------------------------
void SoLuaBind::ExecuteBind(lua_CFunction pBindFunc)
{
if (ms_L == 0)
{
return;
}
lua_pushcfunction(ms_L, pBindFunc);
if (lua_pcall(ms_L, 0, 0, 0) == 0)
{
//执行成功,什么也不做。
}
else
{
if (ms_bHandleError)
{
const char* pszErrorMsg = lua_tostring(ms_L, -1);
SoLuaErrorHandle::Print("SoLuaBind::ExecuteBind : %s", pszErrorMsg);
}
lua_pop(ms_L, 1); //把错误提示信息弹出栈
}
}
//-----------------------------------------------------------------------------
bool SoLuaBind::FuncBegin()
{
//清零
ms_nPopSize = 0;
ms_nBindResultCount = 0;
//获取参数的个数
const int nCount = lua_gettop(ms_L);
if (nCount > SoLuaBind_MaxCount)
{
if (ms_bHandleError)
{
SoLuaErrorHandle::Print("SoLuaBind::FuncBegin : too many params");
}
return false;
}
bool br = true;
//取出所有的参数
for (int i = -nCount; i < 0; ++i)
{
if (CopyResultValue(i, &(ms_kPopElementList[ms_nPopSize])) == false)
{
br = false;
}
++ms_nPopSize;
}
return br;
}
//-----------------------------------------------------------------------------
double SoLuaBind::GetDouble(int nIndex, double dfDefault)
{
double dfValue = dfDefault;
if (nIndex >= 0 && nIndex < ms_nPopSize)
{
if (ms_kPopElementList[nIndex].nType == ElementType_double)
{
dfValue = ms_kPopElementList[nIndex].dfValue;
}
}
return dfValue;
}
//-----------------------------------------------------------------------------
const char* SoLuaBind::GetString(int nIndex, const char* szDefault)
{
const char* szValue = szDefault;
if (nIndex >= 0 && nIndex < ms_nPopSize)
{
if (ms_kPopElementList[nIndex].nType == ElementType_string)
{
szValue = ms_kPopElementList[nIndex].szValue;
}
}
return szValue;
}
//-----------------------------------------------------------------------------
bool SoLuaBind::GetBool(int nIndex, bool bDefault)
{
bool bValue = bDefault;
if (nIndex >= 0 && nIndex < ms_nPopSize)
{
if (ms_kPopElementList[nIndex].nType == ElementType_bool)
{
bValue = (ms_kPopElementList[nIndex].dfValue > 0.0);
}
}
return bValue;
}
//--------------------------------------------------------------------
void SoLuaBind::PushKey(double dfValue)
{
if (ms_nPushSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPushElementList[ms_nPushSize].nType = ElementType_double;
ms_kPushElementList[ms_nPushSize].dfValue = dfValue;
++ms_nPushSize;
}
//--------------------------------------------------------------------
void SoLuaBind::PushKey(const char* szValue)
{
if (ms_nPushSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPushElementList[ms_nPushSize].nType = ElementType_string;
ms_kPushElementList[ms_nPushSize].szValue = szValue;
++ms_nPushSize;
}
//--------------------------------------------------------------------
void SoLuaBind::PushKey(bool bValue)
{
if (ms_nPushSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPushElementList[ms_nPushSize].nType = ElementType_bool;
ms_kPushElementList[ms_nPushSize].dfValue = bValue ? 1.0 : -1.0;
++ms_nPushSize;
}
//--------------------------------------------------------------------
void SoLuaBind::PushValue(double dfValue)
{
if (ms_nPopSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPopElementList[ms_nPopSize].nType = ElementType_double;
ms_kPopElementList[ms_nPopSize].dfValue = dfValue;
++ms_nPopSize;
}
//--------------------------------------------------------------------
void SoLuaBind::PushValue(const char* szValue)
{
if (ms_nPopSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPopElementList[ms_nPopSize].nType = ElementType_string;
ms_kPopElementList[ms_nPopSize].szValue = szValue;
++ms_nPopSize;
}
//--------------------------------------------------------------------
void SoLuaBind::PushValue(bool bValue)
{
if (ms_nPopSize > SoLuaBind_MaxCount)
{
return;
}
ms_kPopElementList[ms_nPopSize].nType = ElementType_bool;
ms_kPopElementList[ms_nPopSize].dfValue = bValue ? 1.0 : -1.0;
++ms_nPopSize;
}
//-----------------------------------------------------------------------------
bool SoLuaBind::ArrayEnd(const char* szArrayName)
{
if (szArrayName == 0 || szArrayName[0] == 0)
{
return false;
}
lua_createtable(ms_L, ms_nPopSize, 0); //创建一个table,并压入栈
for (int i = 0; i < ms_nPopSize; ++i)
{
const int theType = ms_kPopElementList[i].nType;
switch (theType)
{
case ElementType_double:
{
lua_pushnumber(ms_L, ms_kPopElementList[i].dfValue); //压入栈
break;
}
case ElementType_string:
{
lua_pushstring(ms_L, ms_kPopElementList[i].szValue); //压入栈
break;
}
case ElementType_bool:
{
int b = ms_kPopElementList[i].dfValue > 0.0 ? 1 : 0;
lua_pushboolean(ms_L, b); //压入栈
break;
}
default:
{
//数组中有个元素是nil
lua_pushnil(ms_L); //压入nil
break;
}
} //switch
//数组下标是 i+1
lua_rawseti(ms_L, -2, i+1); //以(i+1)为key,以栈顶元素为value,插入到位于(-2)位置的table中,然后把栈顶元素弹出,使得table位于栈顶
}
lua_setglobal(ms_L, szArrayName); //将栈顶的table设置到全局变量szArrayName中,并弹出栈顶的table
return true;
}
//-----------------------------------------------------------------------------
bool SoLuaBind::HashEnd(const char* szHashName)
{
if (szHashName == 0 || szHashName[0] == 0)
{
return false;
}
lua_createtable(ms_L, 0, ms_nPushSize); //创建一个table,并压入栈
bool bPushFinish = false;
stElement* pElement[2];
for (int i = 0; i < ms_nPushSize; ++i)
{
pElement[0] = &(ms_kPushElementList[i]);
pElement[1] = &(ms_kPopElementList[i]);
//
for (int k = 0; k < 2; ++k)
{
switch (pElement[k]->nType)
{
case ElementType_double:
{
lua_pushnumber(ms_L, pElement[k]->dfValue); //压入栈
break;
}
case ElementType_string:
{
lua_pushstring(ms_L, pElement[k]->szValue); //压入栈
break;
}
case ElementType_bool:
{
int b = pElement[k]->dfValue > 0.0 ? 1 : 0;
lua_pushboolean(ms_L, b); //压入栈
break;
}
default:
{
//数组中有个元素是nil
lua_pushnil(ms_L); //压入nil
break;
}
} //switch
}
lua_rawset(ms_L, -3); //以栈中-2位置的元素为key,以栈顶元素为value,插入到位于(-3)位置的table中,然后把-2和栈顶元素弹出,使得table位于栈顶
}
lua_setglobal(ms_L, szHashName); //将栈顶的table设置到全局变量szHashName中,并弹出栈顶的table
return true;
}
//-----------------------------------------------------------------------------
bool SoLuaBind::CopyResultValue(const int nStackIndex, stElement* pElement)
{
bool br = true;
const int luatype = lua_type(ms_L, nStackIndex);
switch (luatype)
{
case LUA_TNUMBER:
{
pElement->nType = ElementType_double;
pElement->dfValue = lua_tonumber(ms_L, nStackIndex);
break;
}
case LUA_TSTRING:
{
pElement->nType = ElementType_string;
pElement->szValue = lua_tostring(ms_L, nStackIndex);
break;
}
case LUA_TBOOLEAN:
{
pElement->nType = ElementType_bool;
const int bV = lua_toboolean(ms_L, nStackIndex);
pElement->dfValue = bV ? 1.0 : -1.0;
break;
}
case LUA_TNIL:
{
//脚本逻辑中可能会返回nil,这是正常情况,也要占用一个stElement。
pElement->nType = ElementType_Invalid;
break;
}
default:
{
pElement->nType = ElementType_Invalid;
br = false;
//
if (ms_bHandleError)
{
const char* szTypeName = lua_typename(ms_L, luatype);
SoLuaErrorHandle::Print("SoLuaBind::CopyResultValue : invalid output value type[%s]", szTypeName);
}
break;
}
}
return br;
}
//-----------------------------------------------------------------------------