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; }
112 sq_tostring(vm, index);
115 sq_getstring(vm, -1, &tmp);
118 ptr->push_back((
void *)tmp_str);
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) {
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.