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();
35 for (
void * p : *
this)
free(p);
39 template <
bool Y>
struct YesT {
40 static const bool Yes = Y;
41 static const bool No = !Y;
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> {};
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 ==
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; }
114 sq_tostring(vm, index);
117 sq_getstring(vm, -1, &tmp);
120 ptr->push_back((
void *)tmp_str);
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);
135 std::vector<int32> data;
137 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
139 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
140 data.push_back((int32)tmp);
143 throw sq_throwerror(vm,
"a member of an array used as parameter to a function is not numeric");
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());
163 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes>
struct HelperT;
168 template <
typename Tretval>
170 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
172 return Return(vm, (*func)());
179 template <
typename Tretval>
181 static int SQCall(
void *instance, Tretval (*func)(), HSQUIRRELVM vm)
191 template <
class Tcls,
typename Tretval>
193 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
195 return Return(vm, (instance->*func)());
202 template <
class Tcls,
typename Tretval>
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>
221 static int SQCall(
void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
224 Tretval ret = (*func)(
234 template <
typename Tretval,
typename Targ1>
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 =
nullptr;
743 SQUserPointer real_instance =
nullptr;
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 ==
nullptr)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
769 }
catch (SQInteger &e) {
779 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
783 int nparam = sq_gettop(vm);
784 SQUserPointer ptr =
nullptr;
785 SQUserPointer real_instance =
nullptr;
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 ==
nullptr)
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 =
nullptr;
825 sq_getuserdata(vm, nparam, &ptr, 0);
830 }
catch (SQInteger &e) {
841 template <
typename Tcls,
typename Tmethod>
845 int nparam = sq_gettop(vm);
846 SQUserPointer ptr =
nullptr;
849 sq_getuserdata(vm, nparam, &ptr, 0);
854 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
861 template <
typename Tcls>
865 if (p !=
nullptr) ((Tcls *)p)->Release();
874 template <
typename Tcls,
typename Tmethod,
int Tnparam>
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) {
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.
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...
defines the Squirrel class
Pointers assigned to this class will be free'd when this instance comes out of scope.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
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.