Fix some daylength issues, possible division by zero in main menu.
[openttd-joker.git] / src / script / squirrel_helper.hpp
blob9407f98f6d8274e477c6a874078760a994ac3843
1 /* $Id: squirrel_helper.hpp 23735 2012-01-03 20:26:05Z rubidium $ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */
12 #ifndef SQUIRREL_HELPER_HPP
13 #define SQUIRREL_HELPER_HPP
15 #include "squirrel.hpp"
16 #include "../core/smallvec_type.hpp"
17 #include "../economy_type.h"
18 #include "../string_func.h"
19 #include "squirrel_helper_type.hpp"
21 template <class CL, ScriptType ST> const char *GetClassName();
23 /**
24 * The Squirrel convert routines
26 namespace SQConvert {
27 /**
28 * Pointers assigned to this class will be free'd when this instance
29 * comes out of scope. Useful to make sure you can use stredup(),
30 * without leaking memory.
32 struct SQAutoFreePointers : SmallVector<void *, 1> {
33 ~SQAutoFreePointers()
35 for (uint i = 0; i < this->items; i++) free(this->data[i]);
39 template <bool Y> struct YesT {
40 static const bool Yes = Y;
41 static const bool No = !Y;
44 /**
45 * Helper class to recognize if the given type is void. Usage: 'IsVoidT<T>::Yes'
47 template <typename T> struct IsVoidT : YesT<false> {};
48 template <> struct IsVoidT<void> : YesT<true> {};
50 /**
51 * Helper class to recognize if the function/method return type is void.
53 template <typename Tfunc> struct HasVoidReturnT;
54 /* functions */
55 template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
56 template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
57 template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
58 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
59 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
60 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
61 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> {};
62 /* methods */
63 template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
64 template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
65 template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
66 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
67 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
68 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> {};
69 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> {};
72 /**
73 * Special class to make it possible for the compiler to pick the correct GetParam().
75 template <typename T> class ForceType { };
77 /**
78 * To return a value to squirrel, we call this function. It converts to the right format.
80 template <typename T> static int Return(HSQUIRRELVM vm, T t);
82 template <> inline int Return<uint8> (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; }
83 template <> inline int Return<uint16> (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
84 template <> inline int Return<uint32> (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
85 template <> inline int Return<int8> (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; }
86 template <> inline int Return<int16> (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; }
87 template <> inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; }
88 template <> inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; }
89 template <> inline int Return<Money> (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; }
90 template <> inline int Return<bool> (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; }
91 template <> inline int Return<char *> (HSQUIRRELVM vm, char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; }
92 template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; }
93 template <> inline int Return<void *> (HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; }
94 template <> inline int Return<HSQOBJECT> (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res); return 1; }
96 /**
97 * To get a param from squirrel, we call this function. It converts to the right format.
99 template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
101 template <> inline uint8 GetParam(ForceType<uint8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
102 template <> inline uint16 GetParam(ForceType<uint16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
103 template <> inline uint32 GetParam(ForceType<uint32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
104 template <> inline int8 GetParam(ForceType<int8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
105 template <> inline int16 GetParam(ForceType<int16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
106 template <> inline int32 GetParam(ForceType<int32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
107 template <> inline int64 GetParam(ForceType<int64> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
108 template <> inline Money GetParam(ForceType<Money> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
109 template <> inline bool GetParam(ForceType<bool> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; }
110 template <> inline void *GetParam(ForceType<void *> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
111 template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
113 /* Convert what-ever there is as parameter to a string */
114 sq_tostring(vm, index);
116 const SQChar *tmp;
117 sq_getstring(vm, -1, &tmp);
118 char *tmp_str = stredup(tmp);
119 sq_poptop(vm);
120 *ptr->Append() = (void *)tmp_str;
121 str_validate(tmp_str, tmp_str + strlen(tmp_str));
122 return tmp_str;
125 template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
127 /* Sanity check of the size. */
128 if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
130 SQObject obj;
131 sq_getstackobj(vm, index, &obj);
132 sq_pushobject(vm, obj);
133 sq_pushnull(vm);
135 SmallVector<int32, 2> data;
137 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
138 SQInteger tmp;
139 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
140 *data.Append() = (int32)tmp;
141 } else {
142 sq_pop(vm, 4);
143 throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric");
146 sq_pop(vm, 2);
148 sq_pop(vm, 2);
150 Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
151 arr->size = data.Length();
152 memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
154 *ptr->Append() = arr;
155 return arr;
159 * Helper class to recognize the function type (retval type, args) and use the proper specialization
160 * for SQ callback. The partial specializations for the second arg (Tis_void_retval) are not possible
161 * on the function. Therefore the class is used instead.
163 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
166 * The real C++ caller for function with return value and 0 params.
168 template <typename Tretval>
169 struct HelperT<Tretval (*)(), false> {
170 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
172 return Return(vm, (*func)());
177 * The real C++ caller for function with no return value and 0 params.
179 template <typename Tretval>
180 struct HelperT<Tretval (*)(), true> {
181 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
183 (*func)();
184 return 0;
189 * The real C++ caller for method with return value and 0 params.
191 template <class Tcls, typename Tretval>
192 struct HelperT<Tretval (Tcls::*)(), false> {
193 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
195 return Return(vm, (instance->*func)());
200 * The real C++ caller for method with no return value and 0 params.
202 template <class Tcls, typename Tretval>
203 struct HelperT<Tretval (Tcls::*)(), true> {
204 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
206 (instance->*func)();
207 return 0;
210 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
212 return new Tcls();
217 * The real C++ caller for function with return value and 1 param.
219 template <typename Tretval, typename Targ1>
220 struct HelperT<Tretval (*)(Targ1), false> {
221 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
223 SQAutoFreePointers ptr;
224 Tretval ret = (*func)(
225 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
227 return Return(vm, ret);
232 * The real C++ caller for function with no return value and 1 param.
234 template <typename Tretval, typename Targ1>
235 struct HelperT<Tretval (*)(Targ1), true> {
236 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
238 SQAutoFreePointers ptr;
239 (*func)(
240 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
242 return 0;
247 * The real C++ caller for method with return value and 1 param.
249 template <class Tcls, typename Tretval, typename Targ1>
250 struct HelperT<Tretval (Tcls::*)(Targ1), false> {
251 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
253 SQAutoFreePointers ptr;
254 Tretval ret = (instance->*func)(
255 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
257 return Return(vm, ret);
262 * The real C++ caller for method with no return value and 1 param.
264 template <class Tcls, typename Tretval, typename Targ1>
265 struct HelperT<Tretval (Tcls::*)(Targ1), true> {
266 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
268 SQAutoFreePointers ptr;
269 (instance->*func)(
270 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
272 return 0;
275 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
277 SQAutoFreePointers ptr;
278 Tcls *inst = new Tcls(
279 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
282 return inst;
287 * The real C++ caller for function with return value and 2 params.
289 template <typename Tretval, typename Targ1, typename Targ2>
290 struct HelperT<Tretval (*)(Targ1, Targ2), false> {
291 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
293 SQAutoFreePointers ptr;
294 Tretval ret = (*func)(
295 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
296 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
298 return Return(vm, ret);
303 * The real C++ caller for function with no return value and 2 params.
305 template <typename Tretval, typename Targ1, typename Targ2>
306 struct HelperT<Tretval (*)(Targ1, Targ2), true> {
307 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
309 SQAutoFreePointers ptr;
310 (*func)(
311 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
312 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
314 return 0;
319 * The real C++ caller for method with return value and 2 params.
321 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
322 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
323 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
325 SQAutoFreePointers ptr;
326 Tretval ret = (instance->*func)(
327 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
328 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
330 return Return(vm, ret);
335 * The real C++ caller for method with no return value and 2 params.
337 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
338 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
339 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
341 SQAutoFreePointers ptr;
342 (instance->*func)(
343 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
344 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
346 return 0;
349 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
351 SQAutoFreePointers ptr;
352 Tcls *inst = new Tcls(
353 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
354 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
357 return inst;
362 * The real C++ caller for function with return value and 3 params.
364 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
365 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
366 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
368 SQAutoFreePointers ptr;
369 Tretval ret = (*func)(
370 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
371 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
372 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
374 return Return(vm, ret);
379 * The real C++ caller for function with no return value and 3 params.
381 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
382 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
383 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
385 SQAutoFreePointers ptr;
386 (*func)(
387 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
388 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
389 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
391 return 0;
396 * The real C++ caller for method with return value and 3 params.
398 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
399 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
400 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
402 SQAutoFreePointers ptr;
403 Tretval ret = (instance->*func)(
404 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
405 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
406 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
408 return Return(vm, ret);
413 * The real C++ caller for method with no return value and 3 params.
415 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
416 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
417 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
419 SQAutoFreePointers ptr;
420 (instance->*func)(
421 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
422 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
423 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
425 return 0;
428 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
430 SQAutoFreePointers ptr;
431 Tcls *inst = new Tcls(
432 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
433 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
434 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
437 return inst;
442 * The real C++ caller for function with return value and 4 params.
444 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
445 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
446 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
448 SQAutoFreePointers ptr;
449 Tretval ret = (*func)(
450 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
451 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
452 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
453 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
455 return Return(vm, ret);
460 * The real C++ caller for function with no return value and 4 params.
462 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
463 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
464 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
466 SQAutoFreePointers ptr;
467 (*func)(
468 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
469 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
470 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
471 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
473 return 0;
478 * The real C++ caller for method with return value and 4 params.
480 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
481 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
482 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
484 SQAutoFreePointers ptr;
485 Tretval ret = (instance->*func)(
486 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
487 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
488 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
489 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
491 return Return(vm, ret);
496 * The real C++ caller for method with no return value and 4 params.
498 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
499 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
500 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
502 SQAutoFreePointers ptr;
503 (instance->*func)(
504 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
505 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
506 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
507 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
509 return 0;
512 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
514 SQAutoFreePointers ptr;
515 Tcls *inst = new Tcls(
516 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
517 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
518 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
519 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
522 return inst;
527 * The real C++ caller for function with return value and 5 params.
529 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
530 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
531 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
533 SQAutoFreePointers ptr;
534 Tretval ret = (*func)(
535 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
536 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
537 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
538 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
539 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
541 return Return(vm, ret);
546 * The real C++ caller for function with no return value and 5 params.
548 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
549 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
550 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
552 SQAutoFreePointers ptr;
553 (*func)(
554 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
555 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
556 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
557 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
558 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
560 return 0;
565 * The real C++ caller for method with return value and 5 params.
567 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
568 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
569 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
571 SQAutoFreePointers ptr;
572 Tretval ret = (instance->*func)(
573 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
574 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
575 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
576 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
577 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
579 return Return(vm, ret);
584 * The real C++ caller for method with no return value and 5 params.
586 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
587 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
588 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
590 SQAutoFreePointers ptr;
591 (instance->*func)(
592 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
593 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
594 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
595 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
596 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
598 return 0;
601 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
603 SQAutoFreePointers ptr;
604 Tcls *inst = new Tcls(
605 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
606 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
607 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
608 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
609 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
612 return inst;
617 * The real C++ caller for function with return value and 10 params.
619 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
620 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
621 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
623 SQAutoFreePointers ptr;
624 Tretval ret = (*func)(
625 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
626 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
627 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
628 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
629 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
630 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
631 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
632 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
633 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
634 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
636 return Return(vm, ret);
641 * The real C++ caller for function with no return value and 10 params.
643 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
644 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
645 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
647 SQAutoFreePointers ptr;
648 (*func)(
649 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
650 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
651 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
652 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
653 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
654 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
655 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
656 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
657 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
658 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
660 return 0;
665 * The real C++ caller for method with return value and 10 params.
667 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>
668 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
669 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
671 SQAutoFreePointers ptr;
672 Tretval ret = (instance->*func)(
673 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
674 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
675 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
676 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
677 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
678 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
679 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
680 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
681 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
682 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
684 return Return(vm, ret);
689 * The real C++ caller for method with no return value and 10 params.
691 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>
692 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
693 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
695 SQAutoFreePointers ptr;
696 (instance->*func)(
697 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
698 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
699 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
700 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
701 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
702 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
703 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
704 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
705 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
706 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
708 return 0;
711 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
713 SQAutoFreePointers ptr;
714 Tcls *inst = new Tcls(
715 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
716 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
717 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
718 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
719 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
720 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
721 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
722 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
723 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
724 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
727 return inst;
733 * A general template for all non-static method callbacks from Squirrel.
734 * In here the function_proc is recovered, and the SQCall is called that
735 * can handle this exact amount of params.
737 template <typename Tcls, typename Tmethod, ScriptType Ttype>
738 inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
740 /* Find the amount of params we got */
741 int nparam = sq_gettop(vm);
742 SQUserPointer ptr = NULL;
743 SQUserPointer real_instance = NULL;
744 HSQOBJECT instance;
746 /* Get the 'SQ' instance of this class */
747 Squirrel::GetInstance(vm, &instance);
749 /* Protect against calls to a non-static method in a static way */
750 sq_pushroottable(vm);
751 const char *className = GetClassName<Tcls, Ttype>();
752 sq_pushstring(vm, className, -1);
753 sq_get(vm, -2);
754 sq_pushobject(vm, instance);
755 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, "class method is non-static");
756 sq_pop(vm, 3);
758 /* Get the 'real' instance of this class */
759 sq_getinstanceup(vm, 1, &real_instance, 0);
760 /* Get the real function pointer */
761 sq_getuserdata(vm, nparam, &ptr, 0);
762 if (real_instance == NULL) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call");
763 /* Remove the userdata from the stack */
764 sq_pop(vm, 1);
766 try {
767 /* Delegate it to a template that can handle this specific function */
768 return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
769 } catch (SQInteger e) {
770 return e;
775 * A general template for all non-static advanced method callbacks from Squirrel.
776 * In here the function_proc is recovered, and the SQCall is called that
777 * can handle this exact amount of params.
779 template <typename Tcls, typename Tmethod, ScriptType Ttype>
780 inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
782 /* Find the amount of params we got */
783 int nparam = sq_gettop(vm);
784 SQUserPointer ptr = NULL;
785 SQUserPointer real_instance = NULL;
786 HSQOBJECT instance;
788 /* Get the 'SQ' instance of this class */
789 Squirrel::GetInstance(vm, &instance);
791 /* Protect against calls to a non-static method in a static way */
792 sq_pushroottable(vm);
793 const char *className = GetClassName<Tcls, Ttype>();
794 sq_pushstring(vm, className, -1);
795 sq_get(vm, -2);
796 sq_pushobject(vm, instance);
797 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, "class method is non-static");
798 sq_pop(vm, 3);
800 /* Get the 'real' instance of this class */
801 sq_getinstanceup(vm, 1, &real_instance, 0);
802 /* Get the real function pointer */
803 sq_getuserdata(vm, nparam, &ptr, 0);
804 if (real_instance == NULL) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call");
805 /* Remove the userdata from the stack */
806 sq_pop(vm, 1);
808 /* Call the function, which its only param is always the VM */
809 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
813 * A general template for all function/static method callbacks from Squirrel.
814 * In here the function_proc is recovered, and the SQCall is called that
815 * can handle this exact amount of params.
817 template <typename Tcls, typename Tmethod>
818 inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
820 /* Find the amount of params we got */
821 int nparam = sq_gettop(vm);
822 SQUserPointer ptr = NULL;
824 /* Get the real function pointer */
825 sq_getuserdata(vm, nparam, &ptr, 0);
827 try {
828 /* Delegate it to a template that can handle this specific function */
829 return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
830 } catch (SQInteger e) {
831 return e;
837 * A general template for all static advanced method callbacks from Squirrel.
838 * In here the function_proc is recovered, and the SQCall is called that
839 * can handle this exact amount of params.
841 template <typename Tcls, typename Tmethod>
842 inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
844 /* Find the amount of params we got */
845 int nparam = sq_gettop(vm);
846 SQUserPointer ptr = NULL;
848 /* Get the real function pointer */
849 sq_getuserdata(vm, nparam, &ptr, 0);
850 /* Remove the userdata from the stack */
851 sq_pop(vm, 1);
853 /* Call the function, which its only param is always the VM */
854 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
858 * A general template for the destructor of SQ instances. This is needed
859 * here as it has to be in the same scope as DefSQConstructorCallback.
861 template <typename Tcls>
862 static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
864 /* Remove the real instance too */
865 if (p != NULL) ((Tcls *)p)->Release();
866 return 0;
870 * A general template to handle creating of instance with any amount of
871 * params. It creates the instance in C++, and it sets all the needed
872 * settings in SQ to register the instance.
874 template <typename Tcls, typename Tmethod, int Tnparam>
875 inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
877 try {
878 /* Create the real instance */
879 Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
880 sq_setinstanceup(vm, -Tnparam, instance);
881 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
882 instance->AddRef();
883 return 0;
884 } catch (SQInteger e) {
885 return e;
890 * A general template to handle creating of an instance with a complex
891 * constructor.
893 template <typename Tcls>
894 inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
896 try {
897 /* Find the amount of params we got */
898 int nparam = sq_gettop(vm);
900 /* Create the real instance */
901 Tcls *instance = new Tcls(vm);
902 sq_setinstanceup(vm, -nparam, instance);
903 sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
904 instance->AddRef();
905 return 0;
906 } catch (SQInteger e) {
907 return e;
911 } // namespace SQConvert
913 #endif /* SQUIRREL_HELPER_HPP */