12 #ifndef SQUIRREL_HELPER_HPP
13 #define SQUIRREL_HELPER_HPP
16 #include "../core/smallvec_type.hpp"
17 #include "../economy_type.h"
18 #include "../string_func.h"
21 template <
class CL, ScriptType ST>
const char *GetClassName();
39 template <
bool Y>
struct YesT {
40 static const bool Yes = Y;
41 static const bool No = !Y;
53 template <
typename Tfunc>
struct HasVoidReturnT;
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> {};
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> {};
80 template <
typename T>
static int Return(HSQUIRRELVM vm, T t);
82 template <>
inline int Return<uint8> (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res);
return 1; }
83 template <>
inline int Return<uint16> (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res);
return 1; }
84 template <>
inline int Return<uint32> (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res);
return 1; }
85 template <>
inline int Return<int8> (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res);
return 1; }
86 template <>
inline int Return<int16> (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res);
return 1; }
87 template <>
inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res);
return 1; }
88 template <>
inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res);
return 1; }
89 template <>
inline int Return<Money> (HSQUIRRELVM vm,
Money res) { sq_pushinteger(vm, res);
return 1; }
90 template <>
inline int Return<bool> (HSQUIRRELVM vm,
bool res) { sq_pushbool (vm, res);
return 1; }
91 template <>
inline int Return<char *> (HSQUIRRELVM vm,
char *res) {
if (res == NULL) sq_pushnull(vm);
else { sq_pushstring(vm, res, -1);
free(res); }
return 1; }
92 template <>
inline int Return<const char *>(HSQUIRRELVM vm,
const char *res) {
if (res == NULL) sq_pushnull(vm);
else { sq_pushstring(vm, res, -1); }
return 1; }
93 template <>
inline int Return<void *> (HSQUIRRELVM vm,
void *res) { sq_pushuserpointer(vm, res);
return 1; }
94 template <>
inline int Return<HSQOBJECT> (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res);
return 1; }
99 template <
typename T>
static T
GetParam(ForceType<T>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr);
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)
114 sq_tostring(vm, index);
117 sq_getstring(vm, -1, &tmp);
120 *ptr->Append() = (
void *)tmp_str;
125 template <>
inline Array *
GetParam(ForceType<Array *>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr)
128 if (sq_getsize(vm, index) > UINT16_MAX)
throw sq_throwerror(vm,
"an array used as parameter to a function is too large");
131 sq_getstackobj(vm, index, &obj);
132 sq_pushobject(vm, obj);
137 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
139 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
140 *data.
Append() = (int32)tmp;
143 throw sq_throwerror(vm,
"a member of an array used as parameter to a function is not numeric");
154 *ptr->Append() = arr;
163 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes>
struct HelperT;
168 template <
typename Tretval>
169 struct HelperT<Tretval (*)(),
false> {
170 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
172 return Return(vm, (*func)());
179 template <
typename Tretval>
180 struct HelperT<Tretval (*)(),
true> {
181 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
191 template <
class Tcls,
typename Tretval>
192 struct HelperT<Tretval (Tcls::*)(), false> {
193 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
195 return Return(vm, (instance->*func)());
202 template <
class Tcls,
typename Tretval>
203 struct HelperT<Tretval (Tcls::*)(), true> {
204 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
210 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
219 template <
typename Tretval,
typename Targ1>
220 struct HelperT<Tretval (*)(Targ1),
false> {
221 static int SQCall(
void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
224 Tretval ret = (*func)(
234 template <
typename Tretval,
typename Targ1>
235 struct HelperT<Tretval (*)(Targ1),
true> {
236 static int SQCall(
void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
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)
254 Tretval ret = (instance->*func)(
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)
275 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
278 Tcls *inst =
new Tcls(
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)
294 Tretval ret = (*func)(
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)
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)
326 Tretval ret = (instance->*func)(
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)
349 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
352 Tcls *inst =
new Tcls(
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)
369 Tretval ret = (*func)(
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)
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)
403 Tretval ret = (instance->*func)(
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)
428 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
431 Tcls *inst =
new Tcls(
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)
449 Tretval ret = (*func)(
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)
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)
485 Tretval ret = (instance->*func)(
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)
512 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
515 Tcls *inst =
new Tcls(
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)
534 Tretval ret = (*func)(
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)
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)
572 Tretval ret = (instance->*func)(
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)
601 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
604 Tcls *inst =
new Tcls(
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)
624 Tretval ret = (*func)(
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)
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)
672 Tretval ret = (instance->*func)(
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)
711 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
714 Tcls *inst =
new Tcls(
737 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
741 int nparam = sq_gettop(vm);
742 SQUserPointer ptr = NULL;
743 SQUserPointer real_instance = NULL;
750 sq_pushroottable(vm);
751 const char *className = GetClassName<Tcls, Ttype>();
752 sq_pushstring(vm, className, -1);
754 sq_pushobject(vm, instance);
755 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
759 sq_getinstanceup(vm, 1, &real_instance, 0);
761 sq_getuserdata(vm, nparam, &ptr, 0);
762 if (real_instance == NULL)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
768 return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
769 }
catch (SQInteger e) {
779 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
783 int nparam = sq_gettop(vm);
784 SQUserPointer ptr = NULL;
785 SQUserPointer real_instance = NULL;
792 sq_pushroottable(vm);
793 const char *className = GetClassName<Tcls, Ttype>();
794 sq_pushstring(vm, className, -1);
796 sq_pushobject(vm, instance);
797 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
801 sq_getinstanceup(vm, 1, &real_instance, 0);
803 sq_getuserdata(vm, nparam, &ptr, 0);
804 if (real_instance == NULL)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
809 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
817 template <
typename Tcls,
typename Tmethod>
821 int nparam = sq_gettop(vm);
822 SQUserPointer ptr = NULL;
825 sq_getuserdata(vm, nparam, &ptr, 0);
829 return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
830 }
catch (SQInteger e) {
841 template <
typename Tcls,
typename Tmethod>
845 int nparam = sq_gettop(vm);
846 SQUserPointer ptr = NULL;
849 sq_getuserdata(vm, nparam, &ptr, 0);
854 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
861 template <
typename Tcls>
865 if (p != NULL) ((Tcls *)p)->Release();
874 template <
typename Tcls,
typename Tmethod,
int Tnparam>
879 Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
880 sq_setinstanceup(vm, -Tnparam, instance);
881 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
884 }
catch (SQInteger e) {
893 template <
typename Tcls>
898 int nparam = sq_gettop(vm);
901 Tcls *instance =
new Tcls(vm);
902 sq_setinstanceup(vm, -nparam, instance);
903 sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
906 }
catch (SQInteger e) {