36 template <>
struct Return<uint8_t> {
static inline int Set(HSQUIRRELVM vm, uint8_t res) { sq_pushinteger(vm, (int32_t)res);
return 1; } };
37 template <>
struct Return<uint16_t> {
static inline int Set(HSQUIRRELVM vm, uint16_t res) { sq_pushinteger(vm, (int32_t)res);
return 1; } };
38 template <>
struct Return<uint32_t> {
static inline int Set(HSQUIRRELVM vm, uint32_t res) { sq_pushinteger(vm, (int32_t)res);
return 1; } };
39 template <>
struct Return<int8_t> {
static inline int Set(HSQUIRRELVM vm, int8_t res) { sq_pushinteger(vm, res);
return 1; } };
40 template <>
struct Return<int16_t> {
static inline int Set(HSQUIRRELVM vm, int16_t res) { sq_pushinteger(vm, res);
return 1; } };
41 template <>
struct Return<int32_t> {
static inline int Set(HSQUIRRELVM vm, int32_t res) { sq_pushinteger(vm, res);
return 1; } };
42 template <>
struct Return<int64_t> {
static inline int Set(HSQUIRRELVM vm, int64_t res) { sq_pushinteger(vm, res);
return 1; } };
43 template <>
struct Return<
TileIndex> {
static inline int Set(HSQUIRRELVM vm,
TileIndex res) { sq_pushinteger(vm, (int32_t)res.base());
return 1; } };
44 template <>
struct Return<bool> {
static inline int Set(HSQUIRRELVM vm,
bool res) { sq_pushbool (vm, res);
return 1; } };
45 template <>
struct Return<char *> { };
46 template <>
struct Return<const char *> { };
47 template <>
struct Return<HSQOBJECT> {
static inline int Set(HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res);
return 1; } };
49 template <
typename T>
requires std::is_enum_v<T>
struct Return<T> {
50 static inline int Set(HSQUIRRELVM vm, T res)
57 template <ConvertibleThroughBase T>
struct Return<T> {
58 static inline int Set(HSQUIRRELVM vm, T res)
60 sq_pushinteger(vm, res.base());
65 template <>
struct Return<std::optional<std::string>> {
66 static inline int Set(HSQUIRRELVM vm, std::optional<std::string> res)
68 if (res.has_value()) {
69 sq_pushstring(vm, res.value());
81 template <
typename T>
struct Param;
83 template <>
struct Param<uint8_t> {
static inline uint8_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
84 template <>
struct Param<uint16_t> {
static inline uint16_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
85 template <>
struct Param<uint32_t> {
static inline uint32_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
86 template <>
struct Param<int8_t> {
static inline int8_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
87 template <>
struct Param<int16_t> {
static inline int16_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
88 template <>
struct Param<int32_t> {
static inline int32_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
89 template <>
struct Param<int64_t> {
static inline int64_t Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return tmp; } };
90 template <>
struct Param<
TileIndex> {
static inline TileIndex Get(HSQUIRRELVM vm,
int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp);
return TileIndex((uint32_t)(int32_t)tmp); } };
91 template <>
struct Param<bool> {
static inline bool Get(HSQUIRRELVM vm,
int index) { SQBool tmp; sq_getbool (vm, index, &tmp);
return tmp != 0; } };
92 template <>
struct Param<const char *> { };
94 template <
typename T>
requires std::is_enum_v<T>
struct Param<T> {
95 static inline T Get(HSQUIRRELVM vm,
int index)
98 sq_getinteger(vm, index, &tmp);
99 return static_cast<T
>(tmp);
103 template <ConvertibleThroughBase T>
struct Param<T> {
104 static inline T Get(HSQUIRRELVM vm,
int index)
107 sq_getinteger(vm, index, &tmp);
108 return T{
static_cast<T::BaseType
>(tmp)};
112 template <>
struct Param<const std::string &> {
113 static inline const std::string Get(HSQUIRRELVM vm,
int index)
116 sq_tostring(vm, index);
118 std::string_view view;
119 sq_getstring(vm, -1, view);
126 template <
typename Titem>
128 static inline Array<Titem> Get(HSQUIRRELVM vm,
int index)
131 if (sq_getsize(vm, index) > UINT16_MAX)
throw sq_throwerror(vm,
"an array used as parameter to a function is too large");
134 sq_getstackobj(vm, index, &obj);
135 sq_pushobject(vm, obj);
140 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
160 template <
typename Tretval,
typename... Targs>
162 static int SQCall(
void *instance, Tretval(*func)(Targs...), HSQUIRRELVM vm)
164 return SQCall(instance, func, vm, std::index_sequence_for<Targs...>{});
168 template <
size_t... i>
169 static int SQCall(
void *, Tretval(*func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
171 if constexpr (std::is_void_v<Tretval>) {
177 Tretval ret = (*func)(
188 template <
class Tcls,
typename Tretval,
typename... Targs>
190 static int SQCall(Tcls *instance,
auto func, HSQUIRRELVM vm)
192 return SQCall(instance, func, vm, std::index_sequence_for<Targs...>{});
195 static Tcls *SQConstruct(HSQUIRRELVM vm)
197 return SQConstruct(vm, std::index_sequence_for<Targs...>{});
201 template <
size_t... i>
202 static int SQCall(Tcls *instance,
auto func, [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
204 if constexpr (std::is_void_v<Tretval>) {
210 Tretval ret = (instance->*func)(
217 template <
size_t... i>
218 static Tcls *SQConstruct([[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
220 Tcls *inst =
new Tcls(
231 template <
class Tcls,
typename Tretval,
typename... Targs>
232 struct HelperT<Tretval(Tcls:: *)(Targs...) const> :
HelperT<Tretval(Tcls:: *)(Targs...)> {};
240 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
244 int nparam = sq_gettop(vm);
245 SQUserPointer ptr =
nullptr;
246 SQUserPointer real_instance =
nullptr;
253 sq_pushroottable(vm);
256 sq_pushobject(vm, instance);
257 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
261 sq_getinstanceup(vm, 1, &real_instance,
nullptr);
263 sq_getuserdata(vm, nparam, &ptr,
nullptr);
264 if (real_instance ==
nullptr)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
270 auto cls_instance =
static_cast<Tcls *
>(real_instance);
271 auto method = *
static_cast<Tmethod *
>(ptr);
273 }
catch (SQInteger &e) {
283 template <
typename Tcls,
typename Tmethod, ScriptType Ttype>
287 int nparam = sq_gettop(vm);
288 SQUserPointer ptr =
nullptr;
289 SQUserPointer real_instance =
nullptr;
296 sq_pushroottable(vm);
299 sq_pushobject(vm, instance);
300 if (sq_instanceof(vm) != SQTrue)
return sq_throwerror(vm,
"class method is non-static");
304 sq_getinstanceup(vm, 1, &real_instance,
nullptr);
306 sq_getuserdata(vm, nparam, &ptr,
nullptr);
307 if (real_instance ==
nullptr)
return sq_throwerror(vm,
"couldn't detect real instance of class for non-static call");
313 auto cls_instance =
static_cast<Tcls *
>(real_instance);
314 auto method = *
static_cast<Tmethod *
>(ptr);
315 return static_cast<SQInteger
>((cls_instance->*method)(vm));
316 }
catch (SQInteger &e) {
326 template <
typename Tcls,
typename Tmethod>
330 int nparam = sq_gettop(vm);
331 SQUserPointer ptr =
nullptr;
334 sq_getuserdata(vm, nparam, &ptr,
nullptr);
338 auto cls_instance =
static_cast<Tcls *
>(
nullptr);
339 auto method = *
static_cast<Tmethod *
>(ptr);
341 }
catch (SQInteger &e) {
352 template <
typename Tcls,
typename Tmethod>
356 int nparam = sq_gettop(vm);
357 SQUserPointer ptr =
nullptr;
360 sq_getuserdata(vm, nparam, &ptr,
nullptr);
366 auto method = *
static_cast<Tmethod *
>(ptr);
367 return static_cast<SQInteger
>((*method)(vm));
368 }
catch (SQInteger &e) {
377 template <
typename Tcls>
381 if (p !=
nullptr) ((Tcls *)p)->Release();
390 template <
typename Tcls,
typename Tmethod>
395 int nparam = sq_gettop(vm);
399 sq_setinstanceup(vm, -nparam, instance);
403 }
catch (SQInteger &e) {
412 template <
typename Tcls>
417 int nparam = sq_gettop(vm);
420 Tcls *instance =
new Tcls(vm);
421 sq_setinstanceup(vm, -nparam, instance);
425 }
catch (SQInteger &e) {