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"
17 #include "../tile_type.h"
20 template <
class CL, ScriptType ST>
const char *GetClassName();
34 for (
void * p : *
this)
free(p);
47 template <
typename T>
static int Return(HSQUIRRELVM vm, T t);
49 template <>
inline int Return<uint8> (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res);
return 1; }
50 template <>
inline int Return<uint16> (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res);
return 1; }
51 template <>
inline int Return<uint32> (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res);
return 1; }
52 template <>
inline int Return<int8> (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res);
return 1; }
53 template <>
inline int Return<int16> (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res);
return 1; }
54 template <>
inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res);
return 1; }
55 template <>
inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res);
return 1; }
56 template <>
inline int Return<Money> (HSQUIRRELVM vm,
Money res) { sq_pushinteger(vm, res);
return 1; }
57 template <>
inline int Return<TileIndex> (HSQUIRRELVM vm,
TileIndex res) { sq_pushinteger(vm, (int32)res.
value);
return 1; }
58 template <>
inline int Return<bool> (HSQUIRRELVM vm,
bool res) { sq_pushbool (vm, res);
return 1; }
59 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; }
60 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; }
61 template <>
inline int Return<void *> (HSQUIRRELVM vm,
void *res) { sq_pushuserpointer(vm, res);
return 1; }
62 template <>
inline int Return<HSQOBJECT> (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res);
return 1; }
67 template <
typename T>
static T
GetParam(ForceType<T>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr);
69 template <>
inline uint8
GetParam(ForceType<uint8> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
70 template <>
inline uint16
GetParam(ForceType<uint16> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
71 template <>
inline uint32
GetParam(ForceType<uint32> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
72 template <>
inline int8
GetParam(ForceType<int8> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
73 template <>
inline int16
GetParam(ForceType<int16> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
74 template <>
inline int32
GetParam(ForceType<int32> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
75 template <>
inline int64
GetParam(ForceType<int64> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
76 template <>
inline TileIndex GetParam(ForceType<TileIndex> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return TileIndex((uint32)(int32)tmp); }
77 template <>
inline Money GetParam(ForceType<Money> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; }
78 template <>
inline bool GetParam(ForceType<bool> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp);
return tmp != 0; }
79 template <>
inline void *
GetParam(ForceType<void *> , HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp);
return tmp; }
80 template <>
inline const char *
GetParam(ForceType<const char *>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr)
83 sq_tostring(vm, index);
86 sq_getstring(vm, -1, &tmp);
89 ptr->push_back((
void *)tmp_str);
94 template <>
inline Array *
GetParam(ForceType<Array *>, HSQUIRRELVM vm,
int index, SQAutoFreePointers *ptr)
97 if (sq_getsize(vm, index) > UINT16_MAX)
throw sq_throwerror(vm,
"an array used as parameter to a function is too large");
100 sq_getstackobj(vm, index, &obj);
101 sq_pushobject(vm, obj);
104 std::vector<int32> data;
106 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
108 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
109 data.push_back((int32)tmp);
112 throw sq_throwerror(vm,
"a member of an array used as parameter to a function is not numeric");
119 Array *arr = (
Array*)MallocT<byte>(
sizeof(
Array) +
sizeof(int32) * data.size());
120 arr->
size = data.size();
121 memcpy(arr->
array, data.data(),
sizeof(int32) * data.size());
137 template <
typename Tretval,
typename... Targs>
139 static int SQCall(
void *instance, Tretval(*func)(Targs...), HSQUIRRELVM vm)
141 return SQCall(instance, func, vm, std::index_sequence_for<Targs...>{});
145 template <
size_t... i>
146 static int SQCall(
void *instance, Tretval(*func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
149 if constexpr (std::is_void_v<Tretval>) {
155 Tretval ret = (*func)(
166 template <
class Tcls,
typename Tretval,
typename... Targs>
168 static int SQCall(Tcls *instance, Tretval(Tcls:: *func)(Targs...), HSQUIRRELVM vm)
170 return SQCall(instance, func, vm, std::index_sequence_for<Targs...>{});
173 static Tcls *SQConstruct(Tcls *instance, Tretval(Tcls:: *func)(Targs...), HSQUIRRELVM vm)
175 return SQConstruct(instance, func, vm, std::index_sequence_for<Targs...>{});
179 template <
size_t... i>
180 static int SQCall(Tcls *instance, Tretval(Tcls:: *func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
183 if constexpr (std::is_void_v<Tretval>) {
189 Tretval ret = (instance->*func)(
196 template <
size_t... i>
197 static Tcls *SQConstruct(Tcls *, Tretval(Tcls:: *func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
200 Tcls *inst =
new Tcls(
214 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
218 int nparam = sq_gettop(vm);
219 SQUserPointer ptr =
nullptr;
220 SQUserPointer real_instance =
nullptr;
227 sq_pushroottable(vm);
228 const char *className = GetClassName<Tcls, Ttype>();
229 sq_pushstring(vm, className, -1);
231 sq_pushobject(vm, instance);
232 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
236 sq_getinstanceup(vm, 1, &real_instance,
nullptr);
238 sq_getuserdata(vm, nparam, &ptr,
nullptr);
239 if (real_instance ==
nullptr)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
246 }
catch (SQInteger &e) {
256 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
260 int nparam = sq_gettop(vm);
261 SQUserPointer ptr =
nullptr;
262 SQUserPointer real_instance =
nullptr;
269 sq_pushroottable(vm);
270 const char *className = GetClassName<Tcls, Ttype>();
271 sq_pushstring(vm, className, -1);
273 sq_pushobject(vm, instance);
274 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
278 sq_getinstanceup(vm, 1, &real_instance,
nullptr);
280 sq_getuserdata(vm, nparam, &ptr,
nullptr);
281 if (real_instance ==
nullptr)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
286 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
294 template <
typename Tcls,
typename Tmethod>
298 int nparam = sq_gettop(vm);
299 SQUserPointer ptr =
nullptr;
302 sq_getuserdata(vm, nparam, &ptr,
nullptr);
307 }
catch (SQInteger &e) {
318 template <
typename Tcls,
typename Tmethod>
322 int nparam = sq_gettop(vm);
323 SQUserPointer ptr =
nullptr;
326 sq_getuserdata(vm, nparam, &ptr,
nullptr);
331 return (SQInteger)(*(*(Tmethod *)ptr))(vm);
338 template <
typename Tcls>
342 if (p !=
nullptr) ((Tcls *)p)->Release();
351 template <
typename Tcls,
typename Tmethod,
int Tnparam>
357 sq_setinstanceup(vm, -Tnparam, instance);
358 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
361 }
catch (SQInteger &e) {
370 template <
typename Tcls>
375 int nparam = sq_gettop(vm);
378 Tcls *instance =
new Tcls(vm);
379 sq_setinstanceup(vm, -nparam, instance);
380 sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
383 }
catch (SQInteger &e) {