OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

squirrel_helper.hpp
Go to the documentation of this file.
1 /* $Id: squirrel_helper.hpp 26774 2014-09-06 17:46:56Z rubidium $ */
2
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 */
9
12 #ifndef SQUIRREL_HELPER_HPP
13 #define SQUIRREL_HELPER_HPP
14
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"
20
21 template <class CL, ScriptType ST> const char *GetClassName();
22
26 namespace SQConvert {
32 struct SQAutoFreePointers : SmallVector<void *, 1> {
33 ~SQAutoFreePointers()
34 {
35 for (uint i = 0; i < this->items; i++) free(this->data[i]);
36 }
37 };
38
39 template <bool Y> struct YesT {
40 static const bool Yes = Y;
41 static const bool No = !Y;
42 };
43
47 template <typename T> struct IsVoidT : YesT<false> {};
48 template <> struct IsVoidT<void> : YesT<true> {};
49
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> {};
70
71
75 template <typename T> class ForceType { };
76
80 template <typename T> static int Return(HSQUIRRELVM vm, T t);
81
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; }
95
99 template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
100
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)
112 {
113 /* Convert what-ever there is as parameter to a string */
114 sq_tostring(vm, index);
115
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;
123 }
124
125 template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
126 {
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");
129
130 SQObject obj;
131 sq_getstackobj(vm, index, &obj);
132 sq_pushobject(vm, obj);
133 sq_pushnull(vm);
134
135 SmallVector<int32, 2> data;
136
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");
144 }
145
146 sq_pop(vm, 2);
147 }
148 sq_pop(vm, 2);
149
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());
153
154 *ptr->Append() = arr;
155 return arr;
156 }
157
163 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
164
168 template <typename Tretval>
169 struct HelperT<Tretval (*)(), false> {
170 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
171 {
172 return Return(vm, (*func)());
173 }
174 };
175
179 template <typename Tretval>
180 struct HelperT<Tretval (*)(), true> {
181 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
182 {
183 (*func)();
184 return 0;
185 }
186 };
187
191 template <class Tcls, typename Tretval>
192 struct HelperT<Tretval (Tcls::*)(), false> {
193 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
194 {
195 return Return(vm, (instance->*func)());
196 }
197 };
198
202 template <class Tcls, typename Tretval>
203 struct HelperT<Tretval (Tcls::*)(), true> {
204 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
205 {
206 (instance->*func)();
207 return 0;
208 }
209
210 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
211 {
212 return new Tcls();
213 }
214 };
215
219 template <typename Tretval, typename Targ1>
220 struct HelperT<Tretval (*)(Targ1), false> {
221 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
222 {
223 SQAutoFreePointers ptr;
224 Tretval ret = (*func)(
225 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
226 );
227 return Return(vm, ret);
228 }
229 };
230
234 template <typename Tretval, typename Targ1>
235 struct HelperT<Tretval (*)(Targ1), true> {
236 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
237 {
238 SQAutoFreePointers ptr;
239 (*func)(
240 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
241 );
242 return 0;
243 }
244 };
245
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)
252 {
253 SQAutoFreePointers ptr;
254 Tretval ret = (instance->*func)(
255 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
256 );
257 return Return(vm, ret);
258 }
259 };
260
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)
267 {
268 SQAutoFreePointers ptr;
269 (instance->*func)(
270 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
271 );
272 return 0;
273 }
274
275 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
276 {
277 SQAutoFreePointers ptr;
278 Tcls *inst = new Tcls(
279 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
280 );
281
282 return inst;
283 }
284 };
285
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)
292 {
293 SQAutoFreePointers ptr;
294 Tretval ret = (*func)(
295 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
296 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
297 );
298 return Return(vm, ret);
299 }
300 };
301
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)
308 {
309 SQAutoFreePointers ptr;
310 (*func)(
311 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
312 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
313 );
314 return 0;
315 }
316 };
317
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)
324 {
325 SQAutoFreePointers ptr;
326 Tretval ret = (instance->*func)(
327 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
328 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
329 );
330 return Return(vm, ret);
331 }
332 };
333
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)
340 {
341 SQAutoFreePointers ptr;
342 (instance->*func)(
343 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
344 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
345 );
346 return 0;
347 }
348
349 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
350 {
351 SQAutoFreePointers ptr;
352 Tcls *inst = new Tcls(
353 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
354 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
355 );
356
357 return inst;
358 }
359 };
360
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)
367 {
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)
373 );
374 return Return(vm, ret);
375 }
376 };
377
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)
384 {
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)
390 );
391 return 0;
392 }
393 };
394
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)
401 {
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)
407 );
408 return Return(vm, ret);
409 }
410 };
411
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)
418 {
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)
424 );
425 return 0;
426 }
427
428 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
429 {
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)
435 );
436
437 return inst;
438 }
439 };
440
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)
447 {
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)
454 );
455 return Return(vm, ret);
456 }
457 };
458
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)
465 {
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)
472 );
473 return 0;
474 }
475 };
476
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)
483 {
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)
490 );
491 return Return(vm, ret);
492 }
493 };
494
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)
501 {
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)
508 );
509 return 0;
510 }
511
512 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
513 {
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)
520 );
521
522 return inst;
523 }
524 };
525
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)
532 {
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)
540 );
541 return Return(vm, ret);
542 }
543 };
544
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)
551 {
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)
559 );
560 return 0;
561 }
562 };
563
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)
570 {
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)
578 );
579 return Return(vm, ret);
580 }
581 };
582
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)
589 {
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)
597 );
598 return 0;
599 }
600
601 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
602 {
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)
610 );
611
612 return inst;
613 }
614 };
615
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)
622 {
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)
635 );
636 return Return(vm, ret);
637 }
638 };
639
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)
646 {
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)
659 );
660 return 0;
661 }
662 };
663
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)
670 {
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)
683 );
684 return Return(vm, ret);
685 }
686 };
687
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)
694 {
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)
707 );
708 return 0;
709 }
710
711 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
712 {
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)
725 );
726
727 return inst;
728 }
729 };
730
731
737 template <typename Tcls, typename Tmethod, ScriptType Ttype>
738 inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
739 {
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;
745
746 /* Get the 'SQ' instance of this class */
747 Squirrel::GetInstance(vm, &instance);
748
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);
757
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);
765
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;
771 }
772 }
773
779 template <typename Tcls, typename Tmethod, ScriptType Ttype>
780 inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
781 {
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;
787
788 /* Get the 'SQ' instance of this class */
789 Squirrel::GetInstance(vm, &instance);
790
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);
799
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);
807
808 /* Call the function, which its only param is always the VM */
809 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
810 }
811
817 template <typename Tcls, typename Tmethod>
818 inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
819 {
820 /* Find the amount of params we got */
821 int nparam = sq_gettop(vm);
822 SQUserPointer ptr = NULL;
823
824 /* Get the real function pointer */
825 sq_getuserdata(vm, nparam, &ptr, 0);
826
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;
832 }
833 }
834
835
841 template <typename Tcls, typename Tmethod>
842 inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
843 {
844 /* Find the amount of params we got */
845 int nparam = sq_gettop(vm);
846 SQUserPointer ptr = NULL;
847
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);
852
853 /* Call the function, which its only param is always the VM */
854 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
855 }
856
861 template <typename Tcls>
862 static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
863 {
864 /* Remove the real instance too */
865 if (p != NULL) ((Tcls *)p)->Release();
866 return 0;
867 }
868
874 template <typename Tcls, typename Tmethod, int Tnparam>
875 inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
876 {
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;
886 }
887 }
888
893 template <typename Tcls>
894 inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
895 {
896 try {
897 /* Find the amount of params we got */
898 int nparam = sq_gettop(vm);
899
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;
908 }
909 }
910
911 } // namespace SQConvert
912
913 #endif /* SQUIRREL_HELPER_HPP */