10 #ifndef SQUIRREL_HELPER_HPP
11 #define SQUIRREL_HELPER_HPP
14 #include "../core/smallvec_type.hpp"
15 #include "../economy_type.h"
16 #include "../string_func.h"
19 template <
class CL, ScriptType ST>
const char *GetClassName();
33 for (
void * p : *
this)
free(p);
37 template <
bool Y>
struct YesT {
38 static const bool Yes = Y;
39 static const bool No = !Y;
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> {};
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> {};
78 template <
typename T>
static int Return(HSQUIRRELVM vm, T t);
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; }
97 template <
typename T>
static T
GetParam(ForceType<T>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr);
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)
112 sq_tostring(vm, index);
115 sq_getstring(vm, -1, &tmp);
118 ptr->push_back((
void *)tmp_str);
123 template <>
inline Array *
GetParam(ForceType<Array *>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr)
126 if (sq_getsize(vm, index) > UINT16_MAX)
throw sq_throwerror(vm,
"an array used as parameter to a function is too large");
129 sq_getstackobj(vm, index, &obj);
130 sq_pushobject(vm, obj);
133 std::vector<int32> data;
135 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
137 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
138 data.push_back((int32)tmp);
141 throw sq_throwerror(vm,
"a member of an array used as parameter to a function is not numeric");
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());
161 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes>
struct HelperT;
166 template <
typename Tretval>
168 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
170 return Return(vm, (*func)());
177 template <
typename Tretval>
179 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
189 template <
class Tcls,
typename Tretval>
191 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
193 return Return(vm, (instance->*func)());
200 template <
class Tcls,
typename Tretval>
202 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
208 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
217 template <
typename Tretval,
typename Targ1>
219 static int SQCall(
void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
222 Tretval ret = (*func)(
232 template <
typename Tretval,
typename Targ1>
234 static int SQCall(
void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
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)
252 Tretval ret = (instance->*func)(
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)
273 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
276 Tcls *inst =
new Tcls(
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)
292 Tretval ret = (*func)(
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)
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)
324 Tretval ret = (instance->*func)(
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)
347 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
350 Tcls *inst =
new Tcls(
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)
367 Tretval ret = (*func)(
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)
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)
401 Tretval ret = (instance->*func)(
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)
426 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
429 Tcls *inst =
new Tcls(
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)
447 Tretval ret = (*func)(
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)
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)
483 Tretval ret = (instance->*func)(
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)
510 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
513 Tcls *inst =
new Tcls(
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)
532 Tretval ret = (*func)(
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)
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)
570 Tretval ret = (instance->*func)(
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)
599 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
602 Tcls *inst =
new Tcls(
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)
622 Tretval ret = (*func)(
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)
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)
670 Tretval ret = (instance->*func)(
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)
709 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
712 Tcls *inst =
new Tcls(
735 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
739 int nparam = sq_gettop(vm);
740 SQUserPointer ptr =
nullptr;
741 SQUserPointer real_instance =
nullptr;
748 sq_pushroottable(vm);
749 const char *className = GetClassName<Tcls, Ttype>();
750 sq_pushstring(vm, className, -1);
752 sq_pushobject(vm, instance);
753 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
757 sq_getinstanceup(vm, 1, &real_instance, 0);
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");
767 }
catch (SQInteger &e) {
777 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
781 int nparam = sq_gettop(vm);
782 SQUserPointer ptr =
nullptr;
783 SQUserPointer real_instance =
nullptr;
790 sq_pushroottable(vm);
791 const char *className = GetClassName<Tcls, Ttype>();
792 sq_pushstring(vm, className, -1);
794 sq_pushobject(vm, instance);
795 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
799 sq_getinstanceup(vm, 1, &real_instance, 0);
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");
807 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
815 template <
typename Tcls,
typename Tmethod>
819 int nparam = sq_gettop(vm);
820 SQUserPointer ptr =
nullptr;
823 sq_getuserdata(vm, nparam, &ptr, 0);
828 }
catch (SQInteger &e) {
839 template <
typename Tcls,
typename Tmethod>
843 int nparam = sq_gettop(vm);
844 SQUserPointer ptr =
nullptr;
847 sq_getuserdata(vm, nparam, &ptr, 0);
852 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
859 template <
typename Tcls>
863 if (p !=
nullptr) ((Tcls *)p)->Release();
872 template <
typename Tcls,
typename Tmethod,
int Tnparam>
878 sq_setinstanceup(vm, -Tnparam, instance);
879 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
882 }
catch (SQInteger &e) {
891 template <
typename Tcls>
896 int nparam = sq_gettop(vm);
899 Tcls *instance =
new Tcls(vm);
900 sq_setinstanceup(vm, -nparam, instance);
901 sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
904 }
catch (SQInteger &e) {