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