OpenTTD Source: src/script/squirrel_helper.hpp Source File

OpenTTD Source 12.2

squirrel_helper.hpp
Go to the documentation of this file.
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10 #ifndef SQUIRREL_HELPER_HPP
11 #define SQUIRREL_HELPER_HPP
12
13 #include "squirrel.hpp"
14 #include "../core/smallvec_type.hpp"
15 #include "../economy_type.h"
16 #include "../string_func.h"
17 #include "squirrel_helper_type.hpp"
18
19 template <class CL, ScriptType ST> const char *GetClassName();
20
24 namespace SQConvert {
30 struct SQAutoFreePointers : std::vector<void *> {
31 ~SQAutoFreePointers()
32 {
33 for (void * p : *this) free(p);
34 }
35 };
36
37 template <bool Y> struct YesT {
38 static const bool Yes = Y;
39 static const bool No = !Y;
40 };
41
45 template <typename T> struct IsVoidT : YesT<false> {};
46 template <> struct IsVoidT<void> : YesT<true> {};
47
51 template <typename Tfunc> struct HasVoidReturnT;
52 /* functions */
53 template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
54 template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
55 template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
56 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
57 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
58 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
59 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10)> : IsVoidT<Tretval> {};
60 /* methods */
61 template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
62 template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
63 template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
64 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
65 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
66 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
67 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10)> : IsVoidT<Tretval> {};
68
69
73 template <typename T> class ForceType { };
74
78 template <typename T> static int Return(HSQUIRRELVM vm, T t);
79
80 template <> inline int Return<uint8> (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; }
81 template <> inline int Return<uint16> (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
82 template <> inline int Return<uint32> (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
83 template <> inline int Return<int8> (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; }
84 template <> inline int Return<int16> (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; }
85 template <> inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; }
86 template <> inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; }
87 template <> inline int Return<Money> (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; }
88 template <> inline int Return<bool> (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; }
89 template <> inline int Return<char *> (HSQUIRRELVM vm, char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; }
90 template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == nullptr) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; }
91 template <> inline int Return<void *> (HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; }
92 template <> inline int Return<HSQOBJECT> (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res); return 1; }
93
97 template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
98
99 template <> inline uint8 GetParam(ForceType<uint8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
100 template <> inline uint16 GetParam(ForceType<uint16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
101 template <> inline uint32 GetParam(ForceType<uint32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
102 template <> inline int8 GetParam(ForceType<int8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
103 template <> inline int16 GetParam(ForceType<int16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
104 template <> inline int32 GetParam(ForceType<int32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
105 template <> inline int64 GetParam(ForceType<int64> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
106 template <> inline Money GetParam(ForceType<Money> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
107 template <> inline bool GetParam(ForceType<bool> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; }
108 template <> inline void *GetParam(ForceType<void *> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
109 template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
110 {
111 /* Convert what-ever there is as parameter to a string */
112 sq_tostring(vm, index);
113
114 const SQChar *tmp;
115 sq_getstring(vm, -1, &tmp);
116 char *tmp_str = stredup(tmp);
117 sq_poptop(vm);
118 ptr->push_back((void *)tmp_str);
119 StrMakeValidInPlace(tmp_str);
120 return tmp_str;
121 }
122
123 template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
124 {
125 /* Sanity check of the size. */
126 if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
127
128 SQObject obj;
129 sq_getstackobj(vm, index, &obj);
130 sq_pushobject(vm, obj);
131 sq_pushnull(vm);
132
133 std::vector<int32> data;
134
135 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
136 SQInteger tmp;
137 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
138 data.push_back((int32)tmp);
139 } else {
140 sq_pop(vm, 4);
141 throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric");
142 }
143
144 sq_pop(vm, 2);
145 }
146 sq_pop(vm, 2);
147
148 Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.size());
149 arr->size = data.size();
150 memcpy(arr->array, data.data(), sizeof(int32) * data.size());
151
152 ptr->push_back(arr);
153 return arr;
154 }
155
161 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
162
166 template <typename Tretval>
167 struct HelperT<Tretval (*)(), false> {
168 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
169 {
170 return Return(vm, (*func)());
171 }
172 };
173
177 template <typename Tretval>
178 struct HelperT<Tretval (*)(), true> {
179 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
180 {
181 (*func)();
182 return 0;
183 }
184 };
185
189 template <class Tcls, typename Tretval>
190 struct HelperT<Tretval (Tcls::*)(), false> {
191 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
192 {
193 return Return(vm, (instance->*func)());
194 }
195 };
196
200 template <class Tcls, typename Tretval>
201 struct HelperT<Tretval (Tcls::*)(), true> {
202 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
203 {
204 (instance->*func)();
205 return 0;
206 }
207
208 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
209 {
210 return new Tcls();
211 }
212 };
213
217 template <typename Tretval, typename Targ1>
218 struct HelperT<Tretval (*)(Targ1), false> {
219 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
220 {
221 SQAutoFreePointers ptr;
222 Tretval ret = (*func)(
223 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
224 );
225 return Return(vm, ret);
226 }
227 };
228
232 template <typename Tretval, typename Targ1>
233 struct HelperT<Tretval (*)(Targ1), true> {
234 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
235 {
236 SQAutoFreePointers ptr;
237 (*func)(
238 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
239 );
240 return 0;
241 }
242 };
243
247 template <class Tcls, typename Tretval, typename Targ1>
248 struct HelperT<Tretval (Tcls::*)(Targ1), false> {
249 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
250 {
251 SQAutoFreePointers ptr;
252 Tretval ret = (instance->*func)(
253 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
254 );
255 return Return(vm, ret);
256 }
257 };
258
262 template <class Tcls, typename Tretval, typename Targ1>
263 struct HelperT<Tretval (Tcls::*)(Targ1), true> {
264 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
265 {
266 SQAutoFreePointers ptr;
267 (instance->*func)(
268 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
269 );
270 return 0;
271 }
272
273 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
274 {
275 SQAutoFreePointers ptr;
276 Tcls *inst = new Tcls(
277 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
278 );
279
280 return inst;
281 }
282 };
283
287 template <typename Tretval, typename Targ1, typename Targ2>
288 struct HelperT<Tretval (*)(Targ1, Targ2), false> {
289 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
290 {
291 SQAutoFreePointers ptr;
292 Tretval ret = (*func)(
293 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
294 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
295 );
296 return Return(vm, ret);
297 }
298 };
299
303 template <typename Tretval, typename Targ1, typename Targ2>
304 struct HelperT<Tretval (*)(Targ1, Targ2), true> {
305 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
306 {
307 SQAutoFreePointers ptr;
308 (*func)(
309 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
310 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
311 );
312 return 0;
313 }
314 };
315
319 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
320 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
321 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
322 {
323 SQAutoFreePointers ptr;
324 Tretval ret = (instance->*func)(
325 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
326 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
327 );
328 return Return(vm, ret);
329 }
330 };
331
335 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
336 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
337 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
338 {
339 SQAutoFreePointers ptr;
340 (instance->*func)(
341 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
342 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
343 );
344 return 0;
345 }
346
347 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
348 {
349 SQAutoFreePointers ptr;
350 Tcls *inst = new Tcls(
351 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
352 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
353 );
354
355 return inst;
356 }
357 };
358
362 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
363 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
364 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
365 {
366 SQAutoFreePointers ptr;
367 Tretval ret = (*func)(
368 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
369 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
370 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
371 );
372 return Return(vm, ret);
373 }
374 };
375
379 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
380 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
381 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
382 {
383 SQAutoFreePointers ptr;
384 (*func)(
385 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
386 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
387 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
388 );
389 return 0;
390 }
391 };
392
396 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
397 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
398 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
399 {
400 SQAutoFreePointers ptr;
401 Tretval ret = (instance->*func)(
402 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
403 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
404 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
405 );
406 return Return(vm, ret);
407 }
408 };
409
413 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
414 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
415 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
416 {
417 SQAutoFreePointers ptr;
418 (instance->*func)(
419 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
420 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
421 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
422 );
423 return 0;
424 }
425
426 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
427 {
428 SQAutoFreePointers ptr;
429 Tcls *inst = new Tcls(
430 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
431 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
432 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
433 );
434
435 return inst;
436 }
437 };
438
442 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
443 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
444 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
445 {
446 SQAutoFreePointers ptr;
447 Tretval ret = (*func)(
448 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
449 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
450 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
451 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
452 );
453 return Return(vm, ret);
454 }
455 };
456
460 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
461 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
462 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
463 {
464 SQAutoFreePointers ptr;
465 (*func)(
466 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
467 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
468 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
469 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
470 );
471 return 0;
472 }
473 };
474
478 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
479 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
480 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
481 {
482 SQAutoFreePointers ptr;
483 Tretval ret = (instance->*func)(
484 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
485 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
486 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
487 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
488 );
489 return Return(vm, ret);
490 }
491 };
492
496 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
497 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
498 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
499 {
500 SQAutoFreePointers ptr;
501 (instance->*func)(
502 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
503 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
504 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
505 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
506 );
507 return 0;
508 }
509
510 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
511 {
512 SQAutoFreePointers ptr;
513 Tcls *inst = new Tcls(
514 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
515 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
516 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
517 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
518 );
519
520 return inst;
521 }
522 };
523
527 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
528 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
529 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
530 {
531 SQAutoFreePointers ptr;
532 Tretval ret = (*func)(
533 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
534 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
535 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
536 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
537 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
538 );
539 return Return(vm, ret);
540 }
541 };
542
546 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
547 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
548 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
549 {
550 SQAutoFreePointers ptr;
551 (*func)(
552 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
553 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
554 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
555 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
556 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
557 );
558 return 0;
559 }
560 };
561
565 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
566 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
567 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
568 {
569 SQAutoFreePointers ptr;
570 Tretval ret = (instance->*func)(
571 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
572 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
573 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
574 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
575 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
576 );
577 return Return(vm, ret);
578 }
579 };
580
584 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
585 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
586 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
587 {
588 SQAutoFreePointers ptr;
589 (instance->*func)(
590 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
591 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
592 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
593 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
594 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
595 );
596 return 0;
597 }
598
599 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
600 {
601 SQAutoFreePointers ptr;
602 Tcls *inst = new Tcls(
603 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
604 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
605 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
606 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
607 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
608 );
609
610 return inst;
611 }
612 };
613
617 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
618 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
619 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
620 {
621 SQAutoFreePointers ptr;
622 Tretval ret = (*func)(
623 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
624 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
625 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
626 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
627 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
628 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
629 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
630 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
631 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
632 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
633 );
634 return Return(vm, ret);
635 }
636 };
637
641 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
642 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
643 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
644 {
645 SQAutoFreePointers ptr;
646 (*func)(
647 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
648 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
649 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
650 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
651 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
652 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
653 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
654 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
655 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
656 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
657 );
658 return 0;
659 }
660 };
661
665 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
666 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
667 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
668 {
669 SQAutoFreePointers ptr;
670 Tretval ret = (instance->*func)(
671 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
672 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
673 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
674 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
675 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
676 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
677 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
678 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
679 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
680 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
681 );
682 return Return(vm, ret);
683 }
684 };
685
689 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
690 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
691 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
692 {
693 SQAutoFreePointers ptr;
694 (instance->*func)(
695 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
696 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
697 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
698 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
699 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
700 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
701 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
702 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
703 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
704 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
705 );
706 return 0;
707 }
708
709 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
710 {
711 SQAutoFreePointers ptr;
712 Tcls *inst = new Tcls(
713 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
714 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
715 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
716 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
717 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
718 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
719 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
720 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
721 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
722 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
723 );
724
725 return inst;
726 }
727 };
728
729
735 template <typename Tcls, typename Tmethod, ScriptType Ttype>
736 inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
737 {
738 /* Find the amount of params we got */
739 int nparam = sq_gettop(vm);
740 SQUserPointer ptr = nullptr;
741 SQUserPointer real_instance = nullptr;
742 HSQOBJECT instance;
743
744 /* Get the 'SQ' instance of this class */
745 Squirrel::GetInstance(vm, &instance);
746
747 /* Protect against calls to a non-static method in a static way */
748 sq_pushroottable(vm);
749 const char *className = GetClassName<Tcls, Ttype>();
750 sq_pushstring(vm, className, -1);
751 sq_get(vm, -2);
752 sq_pushobject(vm, instance);
753 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, "class method is non-static");
754 sq_pop(vm, 3);
755
756 /* Get the 'real' instance of this class */
757 sq_getinstanceup(vm, 1, &real_instance, nullptr);
758 /* Get the real function pointer */
759 sq_getuserdata(vm, nparam, &ptr, nullptr);
760 if (real_instance == nullptr) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call");
761 /* Remove the userdata from the stack */
762 sq_pop(vm, 1);
763
764 try {
765 /* Delegate it to a template that can handle this specific function */
766 return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
767 } catch (SQInteger &e) {
768 return e;
769 }
770 }
771
777 template <typename Tcls, typename Tmethod, ScriptType Ttype>
778 inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
779 {
780 /* Find the amount of params we got */
781 int nparam = sq_gettop(vm);
782 SQUserPointer ptr = nullptr;
783 SQUserPointer real_instance = nullptr;
784 HSQOBJECT instance;
785
786 /* Get the 'SQ' instance of this class */
787 Squirrel::GetInstance(vm, &instance);
788
789 /* Protect against calls to a non-static method in a static way */
790 sq_pushroottable(vm);
791 const char *className = GetClassName<Tcls, Ttype>();
792 sq_pushstring(vm, className, -1);
793 sq_get(vm, -2);
794 sq_pushobject(vm, instance);
795 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, "class method is non-static");
796 sq_pop(vm, 3);
797
798 /* Get the 'real' instance of this class */
799 sq_getinstanceup(vm, 1, &real_instance, nullptr);
800 /* Get the real function pointer */
801 sq_getuserdata(vm, nparam, &ptr, nullptr);
802 if (real_instance == nullptr) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call");
803 /* Remove the userdata from the stack */
804 sq_pop(vm, 1);
805
806 /* Call the function, which its only param is always the VM */
807 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
808 }
809
815 template <typename Tcls, typename Tmethod>
816 inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
817 {
818 /* Find the amount of params we got */
819 int nparam = sq_gettop(vm);
820 SQUserPointer ptr = nullptr;
821
822 /* Get the real function pointer */
823 sq_getuserdata(vm, nparam, &ptr, nullptr);
824
825 try {
826 /* Delegate it to a template that can handle this specific function */
827 return HelperT<Tmethod>::SQCall((Tcls *)nullptr, *(Tmethod *)ptr, vm);
828 } catch (SQInteger &e) {
829 return e;
830 }
831 }
832
833
839 template <typename Tcls, typename Tmethod>
840 inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
841 {
842 /* Find the amount of params we got */
843 int nparam = sq_gettop(vm);
844 SQUserPointer ptr = nullptr;
845
846 /* Get the real function pointer */
847 sq_getuserdata(vm, nparam, &ptr, nullptr);
848 /* Remove the userdata from the stack */
849 sq_pop(vm, 1);
850
851 /* Call the function, which its only param is always the VM */
852 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
853 }
854
859 template <typename Tcls>
860 static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
861 {
862 /* Remove the real instance too */
863 if (p != nullptr) ((Tcls *)p)->Release();
864 return 0;
865 }
866
872 template <typename Tcls, typename Tmethod, int Tnparam>
873 inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
874 {
875 try {
876 /* Create the real instance */
877 Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)nullptr, (Tmethod)nullptr, vm);
878 sq_setinstanceup(vm, -Tnparam, instance);
879 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
880 instance->AddRef();
881 return 0;
882 } catch (SQInteger &e) {
883 return e;
884 }
885 }
886
891 template <typename Tcls>
892 inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
893 {
894 try {
895 /* Find the amount of params we got */
896 int nparam = sq_gettop(vm);
897
898 /* Create the real instance */
899 Tcls *instance = new Tcls(vm);
900 sq_setinstanceup(vm, -nparam, instance);
901 sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
902 instance->AddRef();
903 return 0;
904 } catch (SQInteger &e) {
905 return e;
906 }
907 }
908
909 } // namespace SQConvert
910
911 #endif /* SQUIRREL_HELPER_HPP */
SQConvert::DefSQStaticCallback
SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
A general template for all function/static method callbacks from Squirrel.
Definition: squirrel_helper.hpp:816
SQConvert::SQAutoFreePointers
Pointers assigned to this class will be free'd when this instance comes out of scope.
Definition: squirrel_helper.hpp:30
SQConvert::IsVoidT
Helper class to recognize if the given type is void.
Definition: squirrel_helper.hpp:45
Squirrel::GetInstance
static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr, int pos=1)
Get the Squirrel-instance pointer.
Definition: squirrel.hpp:200
SQConvert::DefSQNonStaticCallback
SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
A general template for all non-static method callbacks from Squirrel.
Definition: squirrel_helper.hpp:736
Array
Definition of a simple array.
Definition: squirrel_helper_type.hpp:14
StrMakeValidInPlace
void StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings)
Scans the string for invalid characters and replaces then with a question mark '?' (if not ignored).
Definition: string.cpp:255
SQConvert::DefSQAdvancedConstructorCallback
SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
A general template to handle creating of an instance with a complex constructor.
Definition: squirrel_helper.hpp:892
SQConvert::ForceType
Special class to make it possible for the compiler to pick the correct GetParam().
Definition: squirrel_helper.hpp:73
SQConvert::YesT
Definition: squirrel_helper.hpp:37
SQConvert
The Squirrel convert routines.
Definition: squirrel_helper.hpp:24
squirrel_helper_type.hpp
SQConvert::HasVoidReturnT
Helper class to recognize if the function/method return type is void.
Definition: squirrel_helper.hpp:51
SQConvert::DefSQAdvancedStaticCallback
SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
A general template for all static advanced method callbacks from Squirrel.
Definition: squirrel_helper.hpp:840
Array::array
int32 array[]
The data of the array.
Definition: squirrel_helper_type.hpp:16
SQConvert::DefSQAdvancedNonStaticCallback
SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
A general template for all non-static advanced method callbacks from Squirrel.
Definition: squirrel_helper.hpp:778
Array::size
size_t size
The size of the array.
Definition: squirrel_helper_type.hpp:15
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:137
SQConvert::HelperT
Helper class to recognize the function type (retval type, args) and use the proper specialization for...
Definition: squirrel_helper.hpp:161
OverflowSafeInt< int64 >
SQConvert::Return
static int Return(HSQUIRRELVM vm, T t)
To return a value to squirrel, we call this function.
SQConvert::DefSQDestructorCallback
static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
A general template for the destructor of SQ instances.
Definition: squirrel_helper.hpp:860
SQConvert::DefSQConstructorCallback
SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
A general template to handle creating of instance with any amount of params.
Definition: squirrel_helper.hpp:873
squirrel.hpp
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:460
SQConvert::GetParam
static T GetParam(ForceType< T >, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
To get a param from squirrel, we call this function.