1 /* $Id: squirrel_helper.hpp 23735 2012-01-03 20:26:05Z rubidium $ */
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/>.
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();
24 * The Squirrel convert routines
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> {
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
;
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> {};
51 * Helper class to recognize if the function/method return type is void.
53 template <typename Tfunc
> struct HasVoidReturnT
;
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
> {};
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
> {};
73 * Special class to make it possible for the compiler to pick the correct GetParam().
75 template <typename T
> class ForceType
{ };
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; }
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
);
117 sq_getstring(vm
, -1, &tmp
);
118 char *tmp_str
= stredup(tmp
);
120 *ptr
->Append() = (void *)tmp_str
;
121 str_validate(tmp_str
, tmp_str
+ strlen(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");
131 sq_getstackobj(vm
, index
, &obj
);
132 sq_pushobject(vm
, obj
);
135 SmallVector
<int32
, 2> data
;
137 while (SQ_SUCCEEDED(sq_next(vm
, -2))) {
139 if (SQ_SUCCEEDED(sq_getinteger(vm
, -1, &tmp
))) {
140 *data
.Append() = (int32
)tmp
;
143 throw sq_throwerror(vm
, "a member of an array used as parameter to a function is not numeric");
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
;
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
)
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
)
210 static Tcls
*SQConstruct(Tcls
*instance
, Tretval (Tcls::*func
)(), HSQUIRRELVM vm
)
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
;
240 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
)
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
;
270 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
)
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
)
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
;
311 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
),
312 GetParam(ForceType
<Targ2
>(), vm
, 3, &ptr
)
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
;
343 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
),
344 GetParam(ForceType
<Targ2
>(), vm
, 3, &ptr
)
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
)
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
;
387 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
),
388 GetParam(ForceType
<Targ2
>(), vm
, 3, &ptr
),
389 GetParam(ForceType
<Targ3
>(), vm
, 4, &ptr
)
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
;
421 GetParam(ForceType
<Targ1
>(), vm
, 2, &ptr
),
422 GetParam(ForceType
<Targ2
>(), vm
, 3, &ptr
),
423 GetParam(ForceType
<Targ3
>(), vm
, 4, &ptr
)
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
)
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
;
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
)
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
;
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
)
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
)
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
;
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
)
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
;
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
)
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
)
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
;
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
)
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
;
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
)
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
)
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
;
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);
754 sq_pushobject(vm
, instance
);
755 if (sq_instanceof(vm
) != SQTrue
) return sq_throwerror(vm
, "class method is non-static");
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 */
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
) {
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
;
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);
796 sq_pushobject(vm
, instance
);
797 if (sq_instanceof(vm
) != SQTrue
) return sq_throwerror(vm
, "class method is non-static");
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 */
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);
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
) {
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 */
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();
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
)
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
>);
884 } catch (SQInteger e
) {
890 * A general template to handle creating of an instance with a complex
893 template <typename Tcls
>
894 inline SQInteger
DefSQAdvancedConstructorCallback(HSQUIRRELVM vm
)
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
>);
906 } catch (SQInteger e
) {
911 } // namespace SQConvert
913 #endif /* SQUIRREL_HELPER_HPP */