|
|
|
@ -23,19 +23,6 @@ template <class CL, ScriptType ST> const char *GetClassName();
|
|
|
|
|
* The Squirrel convert routines
|
|
|
|
|
*/
|
|
|
|
|
namespace SQConvert {
|
|
|
|
|
/**
|
|
|
|
|
* Pointers assigned to this class will be free'd when this instance
|
|
|
|
|
* comes out of scope. Useful to make sure you can use stredup(),
|
|
|
|
|
* without leaking memory.
|
|
|
|
|
*/
|
|
|
|
|
struct SQAutoFreePointers : std::vector<void *> {
|
|
|
|
|
~SQAutoFreePointers()
|
|
|
|
|
{
|
|
|
|
|
for (void * p : *this) free(p);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* To return a value to squirrel, we use this helper class. It converts to the right format.
|
|
|
|
|
* We use a class instead of a plain function to allow us to use partial template specializations.
|
|
|
|
@ -74,21 +61,21 @@ namespace SQConvert {
|
|
|
|
|
*/
|
|
|
|
|
template <typename T> struct Param;
|
|
|
|
|
|
|
|
|
|
template <> struct Param<uint8> { static inline uint8 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<uint16> { static inline uint16 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<uint32> { static inline uint32 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int8> { static inline int8 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int16> { static inline int16 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int32> { static inline int32 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int64> { static inline int64 Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<TileIndex> { static inline TileIndex Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } };
|
|
|
|
|
template <> struct Param<Money> { static inline Money Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<bool> { static inline bool Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } };
|
|
|
|
|
template <> struct Param<uint8> { static inline uint8 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<uint16> { static inline uint16 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<uint32> { static inline uint32 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int8> { static inline int8 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int16> { static inline int16 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int32> { static inline int32 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<int64> { static inline int64 Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<TileIndex> { static inline TileIndex Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return TileIndex((uint32)(int32)tmp); } };
|
|
|
|
|
template <> struct Param<Money> { static inline Money Get(HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<bool> { static inline bool Get(HSQUIRRELVM vm, int index) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } };
|
|
|
|
|
template <> struct Param<const char *> { /* Do not use const char *, use std::string& instead. */ };
|
|
|
|
|
template <> struct Param<void *> { static inline void *Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } };
|
|
|
|
|
template <> struct Param<void *> { static inline void *Get(HSQUIRRELVM vm, int index) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; } };
|
|
|
|
|
|
|
|
|
|
template <> struct Param<const std::string &> {
|
|
|
|
|
static inline const std::string Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
|
|
|
|
|
static inline const std::string Get(HSQUIRRELVM vm, int index)
|
|
|
|
|
{
|
|
|
|
|
/* Convert what-ever there is as parameter to a string */
|
|
|
|
|
sq_tostring(vm, index);
|
|
|
|
@ -102,8 +89,8 @@ namespace SQConvert {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template <typename Titem>
|
|
|
|
|
struct Param<Array<Titem>> {
|
|
|
|
|
static inline Array<Titem> Get(HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
|
|
|
|
|
struct Param<Array<Titem> &&> {
|
|
|
|
|
static inline Array<Titem> Get(HSQUIRRELVM vm, int index)
|
|
|
|
|
{
|
|
|
|
|
/* Sanity check of the size. */
|
|
|
|
|
if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
|
|
|
|
@ -116,7 +103,7 @@ namespace SQConvert {
|
|
|
|
|
Array<Titem> data;
|
|
|
|
|
|
|
|
|
|
while (SQ_SUCCEEDED(sq_next(vm, -2))) {
|
|
|
|
|
data.emplace_back(Param<Titem>::Get(vm, -1, ptr));
|
|
|
|
|
data.emplace_back(Param<Titem>::Get(vm, -1));
|
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
|
}
|
|
|
|
|
sq_pop(vm, 2);
|
|
|
|
@ -146,15 +133,14 @@ namespace SQConvert {
|
|
|
|
|
template <size_t... i>
|
|
|
|
|
static int SQCall(void *instance, Tretval(*func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
|
|
|
|
|
{
|
|
|
|
|
[[maybe_unused]] SQAutoFreePointers ptr;
|
|
|
|
|
if constexpr (std::is_void_v<Tretval>) {
|
|
|
|
|
(*func)(
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i, &ptr)...
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i)...
|
|
|
|
|
);
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
Tretval ret = (*func)(
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i, &ptr)...
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i)...
|
|
|
|
|
);
|
|
|
|
|
return Return<Tretval>::Set(vm, ret);
|
|
|
|
|
}
|
|
|
|
@ -180,15 +166,14 @@ namespace SQConvert {
|
|
|
|
|
template <size_t... i>
|
|
|
|
|
static int SQCall(Tcls *instance, Tretval(Tcls:: *func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
|
|
|
|
|
{
|
|
|
|
|
[[maybe_unused]] SQAutoFreePointers ptr;
|
|
|
|
|
if constexpr (std::is_void_v<Tretval>) {
|
|
|
|
|
(instance->*func)(
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i, &ptr)...
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i)...
|
|
|
|
|
);
|
|
|
|
|
return 0;
|
|
|
|
|
} else {
|
|
|
|
|
Tretval ret = (instance->*func)(
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i, &ptr)...
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i)...
|
|
|
|
|
);
|
|
|
|
|
return Return<Tretval>::Set(vm, ret);
|
|
|
|
|
}
|
|
|
|
@ -197,9 +182,8 @@ namespace SQConvert {
|
|
|
|
|
template <size_t... i>
|
|
|
|
|
static Tcls *SQConstruct(Tcls *, Tretval(Tcls:: *func)(Targs...), [[maybe_unused]] HSQUIRRELVM vm, std::index_sequence<i...>)
|
|
|
|
|
{
|
|
|
|
|
[[maybe_unused]] SQAutoFreePointers ptr;
|
|
|
|
|
Tcls *inst = new Tcls(
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i, &ptr)...
|
|
|
|
|
Param<Targs>::Get(vm, 2 + i)...
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
return inst;
|
|
|
|
|