OpenTTD
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> {
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 
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 */