OpenTTD Source  12.0-beta2
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  StrMakeValidInPlace(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, nullptr);
758  /* Get the real function pointer */
759  sq_getuserdata(vm, nparam, &ptr, nullptr);
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, nullptr);
800  /* Get the real function pointer */
801  sq_getuserdata(vm, nparam, &ptr, nullptr);
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, nullptr);
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, nullptr);
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 */
SQConvert::DefSQStaticCallback
SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
A general template for all function/static method callbacks from Squirrel.
Definition: squirrel_helper.hpp:816
SQConvert::SQAutoFreePointers
Pointers assigned to this class will be free'd when this instance comes out of scope.
Definition: squirrel_helper.hpp:30
SQConvert::IsVoidT
Helper class to recognize if the given type is void.
Definition: squirrel_helper.hpp:45
Squirrel::GetInstance
static bool GetInstance(HSQUIRRELVM vm, HSQOBJECT *ptr, int pos=1)
Get the Squirrel-instance pointer.
Definition: squirrel.hpp:200
SQConvert::DefSQNonStaticCallback
SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
A general template for all non-static method callbacks from Squirrel.
Definition: squirrel_helper.hpp:736
Array
Definition of a simple array.
Definition: squirrel_helper_type.hpp:14
StrMakeValidInPlace
void StrMakeValidInPlace(char *str, const char *last, StringValidationSettings settings)
Scans the string for invalid characters and replaces then with a question mark '?' (if not ignored).
Definition: string.cpp:255
SQConvert::DefSQAdvancedConstructorCallback
SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
A general template to handle creating of an instance with a complex constructor.
Definition: squirrel_helper.hpp:892
SQConvert::ForceType
Special class to make it possible for the compiler to pick the correct GetParam().
Definition: squirrel_helper.hpp:73
SQConvert::YesT
Definition: squirrel_helper.hpp:37
SQConvert
The Squirrel convert routines.
Definition: squirrel_helper.hpp:24
squirrel_helper_type.hpp
SQConvert::HasVoidReturnT
Helper class to recognize if the function/method return type is void.
Definition: squirrel_helper.hpp:51
SQConvert::DefSQAdvancedStaticCallback
SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
A general template for all static advanced method callbacks from Squirrel.
Definition: squirrel_helper.hpp:840
Array::array
int32 array[]
The data of the array.
Definition: squirrel_helper_type.hpp:16
SQConvert::DefSQAdvancedNonStaticCallback
SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
A general template for all non-static advanced method callbacks from Squirrel.
Definition: squirrel_helper.hpp:778
Array::size
size_t size
The size of the array.
Definition: squirrel_helper_type.hpp:15
stredup
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:137
SQConvert::HelperT
Helper class to recognize the function type (retval type, args) and use the proper specialization for...
Definition: squirrel_helper.hpp:161
OverflowSafeInt< int64 >
SQConvert::Return
static int Return(HSQUIRRELVM vm, T t)
To return a value to squirrel, we call this function.
SQConvert::DefSQDestructorCallback
static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
A general template for the destructor of SQ instances.
Definition: squirrel_helper.hpp:860
SQConvert::DefSQConstructorCallback
SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
A general template to handle creating of instance with any amount of params.
Definition: squirrel_helper.hpp:873
squirrel.hpp
free
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: stdafx.h:460
SQConvert::GetParam
static T GetParam(ForceType< T >, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
To get a param from squirrel, we call this function.