OpenTTD
squirrel_helper.hpp
Go to the documentation of this file.
1 /* $Id$ */
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 : std::vector<void *> {
34  {
35  for (void * p : *this) free(p);
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 == nullptr) 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 == nullptr) 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->push_back((void *)tmp_str);
121  str_validate(tmp_str, tmp_str + strlen(tmp_str));
122  return tmp_str;
123  }
124 
125  template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
126  {
127  /* Sanity check of the size. */
128  if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
129 
130  SQObject obj;
131  sq_getstackobj(vm, index, &obj);
132  sq_pushobject(vm, obj);
133  sq_pushnull(vm);
134 
135  std::vector<int32> data;
136 
137  while (SQ_SUCCEEDED(sq_next(vm, -2))) {
138  SQInteger tmp;
139  if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
140  data.push_back((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.size());
151  arr->size = data.size();
152  memcpy(arr->array, data.data(), sizeof(int32) * data.size());
153 
154  ptr->push_back(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 = nullptr;
743  SQUserPointer real_instance = nullptr;
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 == nullptr) 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 = nullptr;
785  SQUserPointer real_instance = nullptr;
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 == nullptr) 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 = nullptr;
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 *)nullptr, *(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 = nullptr;
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 != nullptr) ((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 *)nullptr, (Tmethod)nullptr, 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 */
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:202
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:196
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:138
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:131