00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef SQUIRREL_HELPER_HPP
00013 #define SQUIRREL_HELPER_HPP
00014
00015 #include "squirrel.hpp"
00016 #include "../core/math_func.hpp"
00017 #include "../core/smallvec_type.hpp"
00018 #include "../economy_type.h"
00019 #include "../string_func.h"
00020 #include "squirrel_helper_type.hpp"
00021
00025 namespace SQConvert {
00031 struct SQAutoFreePointers : SmallVector<void *, 1> {
00032 ~SQAutoFreePointers()
00033 {
00034 for (uint i = 0; i < this->items; i++) free(this->data[i]);
00035 }
00036 };
00037
00038 template <bool Y> struct YesT {
00039 static const bool Yes = Y;
00040 static const bool No = !Y;
00041 };
00042
00046 template <typename T> struct IsVoidT : YesT<false> {};
00047 template <> struct IsVoidT<void> : YesT<true> {};
00048
00052 template <typename Tfunc> struct HasVoidReturnT;
00053
00054 template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
00055 template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
00056 template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
00057 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
00058 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
00059 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
00060 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> {};
00061
00062 template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
00063 template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
00064 template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
00065 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
00066 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
00067 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> {};
00068 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> {};
00069
00070
00074 template <typename T> class ForceType { };
00075
00079 template <typename T> static int Return(HSQUIRRELVM vm, T t);
00080
00081 template <> inline int Return<uint8> (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; }
00082 template <> inline int Return<uint16> (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
00083 template <> inline int Return<uint32> (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
00084 template <> inline int Return<int8> (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; }
00085 template <> inline int Return<int16> (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; }
00086 template <> inline int Return<int32> (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; }
00087 template <> inline int Return<int64> (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, ClampToI32(res)); return 1; }
00088 template <> inline int Return<Money> (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, ClampToI32(res)); return 1; }
00089 template <> inline int Return<bool> (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; }
00090 template <> inline int Return<char *> (HSQUIRRELVM vm, char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, OTTD2SQ(res), -1); free(res); } return 1; }
00091 template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, OTTD2SQ(res), -1); } return 1; }
00092 template <> inline int Return<void *> (HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; }
00093
00097 template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
00098
00099 template <> inline uint8 GetParam(ForceType<uint8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00100 template <> inline uint16 GetParam(ForceType<uint16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00101 template <> inline uint32 GetParam(ForceType<uint32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00102 template <> inline int8 GetParam(ForceType<int8> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00103 template <> inline int16 GetParam(ForceType<int16> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00104 template <> inline int32 GetParam(ForceType<int32> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
00105 template <> inline bool GetParam(ForceType<bool> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; }
00106 template <> inline void *GetParam(ForceType<void *> , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
00107 template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
00108 {
00109 sq_tostring(vm, index);
00110 const SQChar *tmp;
00111 sq_getstring(vm, -1, &tmp);
00112 char *tmp_str = strdup(SQ2OTTD(tmp));
00113 sq_poptop(vm);
00114 *ptr->Append() = (void *)tmp_str;
00115 str_validate(tmp_str, tmp_str + strlen(tmp_str));
00116 return tmp_str;
00117 }
00118
00119 template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
00120 {
00121
00122 if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, _SC("an array used as parameter to a function is too large"));
00123
00124 SQObject obj;
00125 sq_getstackobj(vm, index, &obj);
00126 sq_pushobject(vm, obj);
00127 sq_pushnull(vm);
00128
00129 SmallVector<int32, 2> data;
00130
00131 while (SQ_SUCCEEDED(sq_next(vm, -2))) {
00132 SQInteger tmp;
00133 if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
00134 *data.Append() = (int32)tmp;
00135 } else {
00136 sq_pop(vm, 4);
00137 throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
00138 }
00139
00140 sq_pop(vm, 2);
00141 }
00142 sq_pop(vm, 2);
00143
00144 Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
00145 arr->size = data.Length();
00146 memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
00147
00148 *ptr->Append() = arr;
00149 return arr;
00150 }
00151
00157 template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
00158
00162 template <typename Tretval>
00163 struct HelperT<Tretval (*)(), false> {
00164 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00165 {
00166 return Return(vm, (*func)());
00167 }
00168 };
00169
00173 template <typename Tretval>
00174 struct HelperT<Tretval (*)(), true> {
00175 static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00176 {
00177 (*func)();
00178 return 0;
00179 }
00180 };
00181
00185 template <class Tcls, typename Tretval>
00186 struct HelperT<Tretval (Tcls::*)(), false> {
00187 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00188 {
00189 return Return(vm, (instance->*func)());
00190 }
00191 };
00192
00196 template <class Tcls, typename Tretval>
00197 struct HelperT<Tretval (Tcls::*)(), true> {
00198 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00199 {
00200 (instance->*func)();
00201 return 0;
00202 }
00203
00204 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00205 {
00206 return new Tcls();
00207 }
00208 };
00209
00213 template <typename Tretval, typename Targ1>
00214 struct HelperT<Tretval (*)(Targ1), false> {
00215 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00216 {
00217 SQAutoFreePointers ptr;
00218 Tretval ret = (*func)(
00219 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00220 );
00221 sq_pop(vm, 1);
00222 return Return(vm, ret);
00223 }
00224 };
00225
00229 template <typename Tretval, typename Targ1>
00230 struct HelperT<Tretval (*)(Targ1), true> {
00231 static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00232 {
00233 SQAutoFreePointers ptr;
00234 (*func)(
00235 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00236 );
00237 sq_pop(vm, 1);
00238 return 0;
00239 }
00240 };
00241
00245 template <class Tcls, typename Tretval, typename Targ1>
00246 struct HelperT<Tretval (Tcls::*)(Targ1), false> {
00247 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00248 {
00249 SQAutoFreePointers ptr;
00250 Tretval ret = (instance->*func)(
00251 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00252 );
00253 sq_pop(vm, 1);
00254 return Return(vm, ret);
00255 }
00256 };
00257
00261 template <class Tcls, typename Tretval, typename Targ1>
00262 struct HelperT<Tretval (Tcls::*)(Targ1), true> {
00263 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00264 {
00265 SQAutoFreePointers ptr;
00266 (instance->*func)(
00267 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00268 );
00269 sq_pop(vm, 1);
00270 return 0;
00271 }
00272
00273 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00274 {
00275 SQAutoFreePointers ptr;
00276 Tcls *inst = new Tcls(
00277 GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00278 );
00279
00280 return inst;
00281 }
00282 };
00283
00287 template <typename Tretval, typename Targ1, typename Targ2>
00288 struct HelperT<Tretval (*)(Targ1, Targ2), false> {
00289 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
00290 {
00291 SQAutoFreePointers ptr;
00292 Tretval ret = (*func)(
00293 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00294 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00295 );
00296 sq_pop(vm, 2);
00297 return Return(vm, ret);
00298 }
00299 };
00300
00304 template <typename Tretval, typename Targ1, typename Targ2>
00305 struct HelperT<Tretval (*)(Targ1, Targ2), true> {
00306 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
00307 {
00308 SQAutoFreePointers ptr;
00309 (*func)(
00310 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00311 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00312 );
00313 sq_pop(vm, 2);
00314 return 0;
00315 }
00316 };
00317
00321 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
00322 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
00323 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00324 {
00325 SQAutoFreePointers ptr;
00326 Tretval ret = (instance->*func)(
00327 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00328 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00329 );
00330 sq_pop(vm, 2);
00331 return Return(vm, ret);
00332 }
00333 };
00334
00338 template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
00339 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
00340 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00341 {
00342 SQAutoFreePointers ptr;
00343 (instance->*func)(
00344 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00345 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00346 );
00347 sq_pop(vm, 2);
00348 return 0;
00349 }
00350
00351 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00352 {
00353 SQAutoFreePointers ptr;
00354 Tcls *inst = new Tcls(
00355 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00356 GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00357 );
00358
00359 return inst;
00360 }
00361 };
00362
00366 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00367 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
00368 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00369 {
00370 SQAutoFreePointers ptr;
00371 Tretval ret = (*func)(
00372 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00373 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00374 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00375 );
00376 sq_pop(vm, 3);
00377 return Return(vm, ret);
00378 }
00379 };
00380
00384 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00385 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
00386 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00387 {
00388 SQAutoFreePointers ptr;
00389 (*func)(
00390 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00391 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00392 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00393 );
00394 sq_pop(vm, 3);
00395 return 0;
00396 }
00397 };
00398
00402 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00403 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
00404 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00405 {
00406 SQAutoFreePointers ptr;
00407 Tretval ret = (instance->*func)(
00408 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00409 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00410 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00411 );
00412 sq_pop(vm, 3);
00413 return Return(vm, ret);
00414 }
00415 };
00416
00420 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00421 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
00422 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00423 {
00424 SQAutoFreePointers ptr;
00425 (instance->*func)(
00426 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00427 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00428 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00429 );
00430 sq_pop(vm, 3);
00431 return 0;
00432 }
00433
00434 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00435 {
00436 SQAutoFreePointers ptr;
00437 Tcls *inst = new Tcls(
00438 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00439 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00440 GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00441 );
00442
00443 return inst;
00444 }
00445 };
00446
00450 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00451 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
00452 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00453 {
00454 SQAutoFreePointers ptr;
00455 Tretval ret = (*func)(
00456 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00457 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00458 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00459 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00460 );
00461 sq_pop(vm, 4);
00462 return Return(vm, ret);
00463 }
00464 };
00465
00469 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00470 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
00471 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00472 {
00473 SQAutoFreePointers ptr;
00474 (*func)(
00475 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00476 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00477 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00478 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00479 );
00480 sq_pop(vm, 4);
00481 return 0;
00482 }
00483 };
00484
00488 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00489 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
00490 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00491 {
00492 SQAutoFreePointers ptr;
00493 Tretval ret = (instance->*func)(
00494 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00495 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00496 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00497 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00498 );
00499 sq_pop(vm, 4);
00500 return Return(vm, ret);
00501 }
00502 };
00503
00507 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00508 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
00509 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00510 {
00511 SQAutoFreePointers ptr;
00512 (instance->*func)(
00513 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00514 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00515 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00516 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00517 );
00518 sq_pop(vm, 4);
00519 return 0;
00520 }
00521
00522 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00523 {
00524 SQAutoFreePointers ptr;
00525 Tcls *inst = new Tcls(
00526 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00527 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00528 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00529 GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00530 );
00531
00532 return inst;
00533 }
00534 };
00535
00539 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00540 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00541 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00542 {
00543 SQAutoFreePointers ptr;
00544 Tretval ret = (*func)(
00545 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00546 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00547 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00548 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00549 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00550 );
00551 sq_pop(vm, 5);
00552 return Return(vm, ret);
00553 }
00554 };
00555
00559 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00560 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00561 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00562 {
00563 SQAutoFreePointers ptr;
00564 (*func)(
00565 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00566 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00567 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00568 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00569 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00570 );
00571 sq_pop(vm, 5);
00572 return 0;
00573 }
00574 };
00575
00579 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00580 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00581 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00582 {
00583 SQAutoFreePointers ptr;
00584 Tretval ret = (instance->*func)(
00585 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00586 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00587 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00588 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00589 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00590 );
00591 sq_pop(vm, 5);
00592 return Return(vm, ret);
00593 }
00594 };
00595
00599 template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00600 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00601 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00602 {
00603 SQAutoFreePointers ptr;
00604 (instance->*func)(
00605 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00606 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00607 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00608 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00609 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00610 );
00611 sq_pop(vm, 5);
00612 return 0;
00613 }
00614
00615 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00616 {
00617 SQAutoFreePointers ptr;
00618 Tcls *inst = new Tcls(
00619 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00620 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00621 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00622 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00623 GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00624 );
00625
00626 return inst;
00627 }
00628 };
00629
00633 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00634 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00635 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00636 {
00637 SQAutoFreePointers ptr;
00638 Tretval ret = (*func)(
00639 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00640 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00641 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00642 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00643 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00644 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00645 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00646 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00647 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00648 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00649 );
00650 sq_pop(vm, 10);
00651 return Return(vm, ret);
00652 }
00653 };
00654
00658 template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00659 struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00660 static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00661 {
00662 SQAutoFreePointers ptr;
00663 (*func)(
00664 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00665 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00666 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00667 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00668 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00669 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00670 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00671 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00672 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00673 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00674 );
00675 sq_pop(vm, 10);
00676 return 0;
00677 }
00678 };
00679
00683 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>
00684 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00685 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00686 {
00687 SQAutoFreePointers ptr;
00688 Tretval ret = (instance->*func)(
00689 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00690 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00691 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00692 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00693 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00694 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00695 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00696 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00697 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00698 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00699 );
00700 sq_pop(vm, 10);
00701 return Return(vm, ret);
00702 }
00703 };
00704
00708 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>
00709 struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00710 static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00711 {
00712 SQAutoFreePointers ptr;
00713 (instance->*func)(
00714 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00715 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00716 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00717 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00718 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00719 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00720 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00721 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00722 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00723 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00724 );
00725 sq_pop(vm, 10);
00726 return 0;
00727 }
00728
00729 static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00730 {
00731 SQAutoFreePointers ptr;
00732 Tcls *inst = new Tcls(
00733 GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00734 GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00735 GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00736 GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00737 GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00738 GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00739 GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00740 GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00741 GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00742 GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00743 );
00744
00745 return inst;
00746 }
00747 };
00748
00749
00755 template <typename Tcls, typename Tmethod>
00756 inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
00757 {
00758
00759 int nparam = sq_gettop(vm);
00760 SQUserPointer ptr = NULL;
00761 SQUserPointer real_instance = NULL;
00762 HSQOBJECT instance;
00763
00764
00765 Squirrel::GetInstance(vm, &instance);
00766
00767
00768 sq_pushroottable(vm);
00769 sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
00770 sq_get(vm, -2);
00771 sq_pushobject(vm, instance);
00772 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00773 sq_pop(vm, 3);
00774
00775
00776 sq_getinstanceup(vm, 1, &real_instance, 0);
00777
00778 sq_getuserdata(vm, nparam, &ptr, 0);
00779 if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00780
00781 sq_pop(vm, 1);
00782
00783 try {
00784
00785 return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
00786 } catch (SQInteger e) {
00787 sq_pop(vm, nparam);
00788 return e;
00789 }
00790 }
00791
00797 template <typename Tcls, typename Tmethod>
00798 inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
00799 {
00800
00801 int nparam = sq_gettop(vm);
00802 SQUserPointer ptr = NULL;
00803 SQUserPointer real_instance = NULL;
00804 HSQOBJECT instance;
00805
00806
00807 Squirrel::GetInstance(vm, &instance);
00808
00809
00810 sq_pushroottable(vm);
00811 sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
00812 sq_get(vm, -2);
00813 sq_pushobject(vm, instance);
00814 if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00815 sq_pop(vm, 3);
00816
00817
00818 sq_getinstanceup(vm, 1, &real_instance, 0);
00819
00820 sq_getuserdata(vm, nparam, &ptr, 0);
00821 if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00822
00823 sq_pop(vm, 1);
00824
00825
00826 return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
00827 }
00828
00834 template <typename Tcls, typename Tmethod>
00835 inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
00836 {
00837
00838 int nparam = sq_gettop(vm);
00839 SQUserPointer ptr = NULL;
00840
00841
00842 sq_getuserdata(vm, nparam, &ptr, 0);
00843
00844 try {
00845
00846 return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
00847 } catch (SQInteger e) {
00848 sq_pop(vm, nparam);
00849 return e;
00850 }
00851 }
00852
00857 template <typename Tcls>
00858 static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
00859 {
00860
00861 if (p != NULL) ((Tcls *)p)->Release();
00862 return 0;
00863 }
00864
00870 template <typename Tcls, typename Tmethod, int Tnparam>
00871 inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
00872 {
00873
00874 int nparam = sq_gettop(vm);
00875
00876 try {
00877
00878 Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
00879 sq_setinstanceup(vm, -Tnparam, instance);
00880 sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
00881 instance->AddRef();
00882 return 0;
00883 } catch (SQInteger e) {
00884 sq_pop(vm, nparam);
00885 return e;
00886 }
00887 }
00888
00889 }
00890
00891 #endif