# squirrel_helper.hpp

Go to the documentation of this file.

    00001 /* $Id: squirrel_helper.hpp 23735 2012-01-03 20:26:05Z rubidium $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
    00006  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    00007  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
    00008  */
    00009
    00012 #ifndef SQUIRREL_HELPER_HPP
    00013 #define SQUIRREL_HELPER_HPP
    00014
    00015 #include "squirrel.hpp"
    00016 #include "../core/smallvec_type.hpp"
    00017 #include "../economy_type.h"
    00018 #include "../string_func.h"
    00019 #include "squirrel_helper_type.hpp"
    00020
    00021 template <class CL, ScriptType ST> const char *GetClassName();
    00022
    00026 namespace SQConvert {
    00032   struct SQAutoFreePointers : SmallVector<void *, 1> {
    00033     ~SQAutoFreePointers()
    00034     {
    00035       for (uint i = 0; i < this->items; i++) free(this->data[i]);
    00036     }
    00037   };
    00038
    00039   template <bool Y> struct YesT {
    00040     static const bool Yes = Y;
    00041     static const bool No = !Y;
    00042   };
    00043
    00047   template <typename T> struct IsVoidT : YesT<false> {};
    00048   template <> struct IsVoidT<void> : YesT<true> {};
    00049
    00053   template <typename Tfunc> struct HasVoidReturnT;
    00054   /* functions */
    00055   template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
    00056   template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
    00057   template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
    00058   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
    00059   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
    00060   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
    00061   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> {};
    00062   /* methods */
    00063   template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
    00064   template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
    00065   template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
    00066   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
    00067   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
    00068   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> {};
    00069   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> {};
    00070
    00071
    00075   template <typename T> class ForceType { };
    00076
    00080   template <typename T> static int Return(HSQUIRRELVM vm, T t);
    00081
    00082   template <> inline int Return<uint8>       (HSQUIRRELVM vm, uint8 res)       { sq_pushinteger(vm, (int32)res); return 1; }
    00083   template <> inline int Return<uint16>      (HSQUIRRELVM vm, uint16 res)      { sq_pushinteger(vm, (int32)res); return 1; }
    00084   template <> inline int Return<uint32>      (HSQUIRRELVM vm, uint32 res)      { sq_pushinteger(vm, (int32)res); return 1; }
    00085   template <> inline int Return<int8>        (HSQUIRRELVM vm, int8 res)        { sq_pushinteger(vm, res); return 1; }
    00086   template <> inline int Return<int16>       (HSQUIRRELVM vm, int16 res)       { sq_pushinteger(vm, res); return 1; }
    00087   template <> inline int Return<int32>       (HSQUIRRELVM vm, int32 res)       { sq_pushinteger(vm, res); return 1; }
    00088   template <> inline int Return<int64>       (HSQUIRRELVM vm, int64 res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
    00089   template <> inline int Return<Money>       (HSQUIRRELVM vm, Money res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
    00090   template <> inline int Return<bool>        (HSQUIRRELVM vm, bool res)        { sq_pushbool   (vm, res); return 1; }
    00091   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; }
    00092   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; }
    00093   template <> inline int Return<void *>      (HSQUIRRELVM vm, void *res)       { sq_pushuserpointer(vm, res); return 1; }
    00094   template <> inline int Return<HSQOBJECT>   (HSQUIRRELVM vm, HSQOBJECT res)   { sq_pushobject(vm, res); return 1; }
    00095
    00099   template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
    00100
    00101   template <> inline uint8       GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00102   template <> inline uint16      GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00103   template <> inline uint32      GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00104   template <> inline int8        GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00105   template <> inline int16       GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00106   template <> inline int32       GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00107   template <> inline bool        GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool        tmp; sq_getbool       (vm, index, &tmp); return tmp != 0; }
    00108   template <> inline void       *GetParam(ForceType<void *>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
    00109   template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
    00110   {
    00111     /* Convert what-ever there is as parameter to a string */
    00112     sq_tostring(vm, index);
    00113
    00114     const SQChar *tmp;
    00115     sq_getstring(vm, -1, &tmp);
    00116     char *tmp_str = strdup(SQ2OTTD(tmp));
    00117     sq_poptop(vm);
    00118     *ptr->Append() = (void *)tmp_str;
    00119     str_validate(tmp_str, tmp_str + strlen(tmp_str));
    00120     return tmp_str;
    00121   }
    00122
    00123   template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
    00124   {
    00125     /* Sanity check of the size. */
    00126     if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, _SC("an array used as parameter to a function is too large"));
    00127
    00128     SQObject obj;
    00129     sq_getstackobj(vm, index, &obj);
    00130     sq_pushobject(vm, obj);
    00131     sq_pushnull(vm);
    00132
    00133     SmallVector<int32, 2> data;
    00134
    00135     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
    00136       SQInteger tmp;
    00137       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
    00138         *data.Append() = (int32)tmp;
    00139       } else {
    00140         sq_pop(vm, 4);
    00141         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
    00142       }
    00143
    00144       sq_pop(vm, 2);
    00145     }
    00146     sq_pop(vm, 2);
    00147
    00148     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
    00149     arr->size = data.Length();
    00150     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
    00151
    00152     *ptr->Append() = arr;
    00153     return arr;
    00154   }
    00155
    00161   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
    00162
    00166   template <typename Tretval>
    00167   struct HelperT<Tretval (*)(), false> {
    00168     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00169     {
    00170       return Return(vm, (*func)());
    00171     }
    00172   };
    00173
    00177   template <typename Tretval>
    00178   struct HelperT<Tretval (*)(), true> {
    00179     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00180     {
    00181       (*func)();
    00182       return 0;
    00183     }
    00184   };
    00185
    00189   template <class Tcls, typename Tretval>
    00190   struct HelperT<Tretval (Tcls::*)(), false> {
    00191     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00192     {
    00193       return Return(vm, (instance->*func)());
    00194     }
    00195   };
    00196
    00200   template <class Tcls, typename Tretval>
    00201   struct HelperT<Tretval (Tcls::*)(), true> {
    00202     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00203     {
    00204       (instance->*func)();
    00205       return 0;
    00206     }
    00207
    00208     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00209     {
    00210       return new Tcls();
    00211     }
    00212   };
    00213
    00217   template <typename Tretval, typename Targ1>
    00218   struct HelperT<Tretval (*)(Targ1), false> {
    00219     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00220     {
    00221       SQAutoFreePointers ptr;
    00222       Tretval ret = (*func)(
    00223         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00224       );
    00225       return Return(vm, ret);
    00226     }
    00227   };
    00228
    00232   template <typename Tretval, typename Targ1>
    00233   struct HelperT<Tretval (*)(Targ1), true> {
    00234     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00235     {
    00236       SQAutoFreePointers ptr;
    00237       (*func)(
    00238         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00239       );
    00240       return 0;
    00241     }
    00242   };
    00243
    00247   template <class Tcls, typename Tretval, typename Targ1>
    00248   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
    00249     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00250     {
    00251       SQAutoFreePointers ptr;
    00252       Tretval ret = (instance->*func)(
    00253         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00254       );
    00255       return Return(vm, ret);
    00256     }
    00257   };
    00258
    00262   template <class Tcls, typename Tretval, typename Targ1>
    00263   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
    00264     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00265     {
    00266       SQAutoFreePointers ptr;
    00267       (instance->*func)(
    00268         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00269       );
    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       return Return(vm, ret);
    00297     }
    00298   };
    00299
    00303   template <typename Tretval, typename Targ1, typename Targ2>
    00304   struct HelperT<Tretval (*)(Targ1, Targ2), true> {
    00305     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00306     {
    00307       SQAutoFreePointers ptr;
    00308       (*func)(
    00309         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00310         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00311       );
    00312       return 0;
    00313     }
    00314   };
    00315
    00319   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00320   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
    00321     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00322     {
    00323       SQAutoFreePointers ptr;
    00324       Tretval ret = (instance->*func)(
    00325         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00326         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00327       );
    00328       return Return(vm, ret);
    00329     }
    00330   };
    00331
    00335   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00336   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
    00337     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00338     {
    00339       SQAutoFreePointers ptr;
    00340       (instance->*func)(
    00341         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00342         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00343       );
    00344       return 0;
    00345     }
    00346
    00347     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00348     {
    00349       SQAutoFreePointers ptr;
    00350       Tcls *inst = new Tcls(
    00351         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00352         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00353       );
    00354
    00355       return inst;
    00356     }
    00357   };
    00358
    00362   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00363   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
    00364     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00365     {
    00366       SQAutoFreePointers ptr;
    00367       Tretval ret = (*func)(
    00368         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00369         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00370         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00371       );
    00372       return Return(vm, ret);
    00373     }
    00374   };
    00375
    00379   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00380   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
    00381     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00382     {
    00383       SQAutoFreePointers ptr;
    00384       (*func)(
    00385         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00386         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00387         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00388       );
    00389       return 0;
    00390     }
    00391   };
    00392
    00396   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00397   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
    00398     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00399     {
    00400       SQAutoFreePointers ptr;
    00401       Tretval ret = (instance->*func)(
    00402         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00403         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00404         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00405       );
    00406       return Return(vm, ret);
    00407     }
    00408   };
    00409
    00413   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00414   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
    00415     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00416     {
    00417       SQAutoFreePointers ptr;
    00418       (instance->*func)(
    00419         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00420         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00421         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00422       );
    00423       return 0;
    00424     }
    00425
    00426     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00427     {
    00428       SQAutoFreePointers ptr;
    00429       Tcls *inst = new Tcls(
    00430         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00431         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00432         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00433       );
    00434
    00435       return inst;
    00436     }
    00437   };
    00438
    00442   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00443   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
    00444     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00445     {
    00446       SQAutoFreePointers ptr;
    00447       Tretval ret = (*func)(
    00448         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00449         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00450         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00451         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00452       );
    00453       return Return(vm, ret);
    00454     }
    00455   };
    00456
    00460   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00461   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
    00462     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00463     {
    00464       SQAutoFreePointers ptr;
    00465       (*func)(
    00466         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00467         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00468         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00469         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00470       );
    00471       return 0;
    00472     }
    00473   };
    00474
    00478   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00479   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
    00480     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00481     {
    00482       SQAutoFreePointers ptr;
    00483       Tretval ret = (instance->*func)(
    00484         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00485         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00486         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00487         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00488       );
    00489       return Return(vm, ret);
    00490     }
    00491   };
    00492
    00496   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00497   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
    00498     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00499     {
    00500       SQAutoFreePointers ptr;
    00501       (instance->*func)(
    00502         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00503         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00504         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00505         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00506       );
    00507       return 0;
    00508     }
    00509
    00510     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00511     {
    00512       SQAutoFreePointers ptr;
    00513       Tcls *inst = new Tcls(
    00514         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00515         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00516         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00517         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00518       );
    00519
    00520       return inst;
    00521     }
    00522   };
    00523
    00527   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00528   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00529     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00530     {
    00531       SQAutoFreePointers ptr;
    00532       Tretval ret = (*func)(
    00533         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00534         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00535         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00536         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00537         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00538       );
    00539       return Return(vm, ret);
    00540     }
    00541   };
    00542
    00546   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00547   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00548     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00549     {
    00550       SQAutoFreePointers ptr;
    00551       (*func)(
    00552         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00553         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00554         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00555         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00556         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00557       );
    00558       return 0;
    00559     }
    00560   };
    00561
    00565   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00566   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00567     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00568     {
    00569       SQAutoFreePointers ptr;
    00570       Tretval ret = (instance->*func)(
    00571         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00572         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00573         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00574         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00575         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00576       );
    00577       return Return(vm, ret);
    00578     }
    00579   };
    00580
    00584   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00585   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00586     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00587     {
    00588       SQAutoFreePointers ptr;
    00589       (instance->*func)(
    00590         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00591         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00592         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00593         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00594         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00595       );
    00596       return 0;
    00597     }
    00598
    00599     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00600     {
    00601       SQAutoFreePointers ptr;
    00602       Tcls *inst = new Tcls(
    00603         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00604         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00605         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00606         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00607         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00608       );
    00609
    00610       return inst;
    00611     }
    00612   };
    00613
    00617   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00618   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00619     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00620     {
    00621       SQAutoFreePointers ptr;
    00622       Tretval ret = (*func)(
    00623         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00624         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00625         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00626         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00627         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00628         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00629         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00630         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00631         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00632         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00633       );
    00634       return Return(vm, ret);
    00635     }
    00636   };
    00637
    00641   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00642   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00643     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00644     {
    00645       SQAutoFreePointers ptr;
    00646       (*func)(
    00647         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00648         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00649         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00650         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00651         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00652         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00653         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00654         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00655         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00656         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00657       );
    00658       return 0;
    00659     }
    00660   };
    00661
    00665   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>
    00666   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00667     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00668     {
    00669       SQAutoFreePointers ptr;
    00670       Tretval ret = (instance->*func)(
    00671         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00672         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00673         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00674         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00675         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00676         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00677         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00678         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00679         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00680         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00681       );
    00682       return Return(vm, ret);
    00683     }
    00684   };
    00685
    00689   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>
    00690   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00691     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00692     {
    00693       SQAutoFreePointers ptr;
    00694       (instance->*func)(
    00695         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00696         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00697         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00698         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00699         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00700         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00701         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00702         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00703         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00704         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00705       );
    00706       return 0;
    00707     }
    00708
    00709     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00710     {
    00711       SQAutoFreePointers ptr;
    00712       Tcls *inst = new Tcls(
    00713         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00714         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00715         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00716         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00717         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00718         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00719         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00720         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00721         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00722         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00723       );
    00724
    00725       return inst;
    00726     }
    00727   };
    00728
    00729
    00735   template <typename Tcls, typename Tmethod, ScriptType Ttype>
    00736   inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
    00737   {
    00738     /* Find the amount of params we got */
    00739     int nparam = sq_gettop(vm);
    00740     SQUserPointer ptr = NULL;
    00741     SQUserPointer real_instance = NULL;
    00742     HSQOBJECT instance;
    00743
    00744     /* Get the 'SQ' instance of this class */
    00745     Squirrel::GetInstance(vm, &instance);
    00746
    00747     /* Protect against calls to a non-static method in a static way */
    00748     sq_pushroottable(vm);
    00749     const char *className = GetClassName<Tcls, Ttype>();
    00750     sq_pushstring(vm, OTTD2SQ(className), -1);
    00751     sq_get(vm, -2);
    00752     sq_pushobject(vm, instance);
    00753     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00754     sq_pop(vm, 3);
    00755
    00756     /* Get the 'real' instance of this class */
    00757     sq_getinstanceup(vm, 1, &real_instance, 0);
    00758     /* Get the real function pointer */
    00759     sq_getuserdata(vm, nparam, &ptr, 0);
    00760     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00761     /* Remove the userdata from the stack */
    00762     sq_pop(vm, 1);
    00763
    00764     try {
    00765       /* Delegate it to a template that can handle this specific function */
    00766       return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
    00767     } catch (SQInteger e) {
    00768       return e;
    00769     }
    00770   }
    00771
    00777   template <typename Tcls, typename Tmethod, ScriptType Ttype>
    00778   inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
    00779   {
    00780     /* Find the amount of params we got */
    00781     int nparam = sq_gettop(vm);
    00782     SQUserPointer ptr = NULL;
    00783     SQUserPointer real_instance = NULL;
    00784     HSQOBJECT instance;
    00785
    00786     /* Get the 'SQ' instance of this class */
    00787     Squirrel::GetInstance(vm, &instance);
    00788
    00789     /* Protect against calls to a non-static method in a static way */
    00790     sq_pushroottable(vm);
    00791     const char *className = GetClassName<Tcls, Ttype>();
    00792     sq_pushstring(vm, OTTD2SQ(className), -1);
    00793     sq_get(vm, -2);
    00794     sq_pushobject(vm, instance);
    00795     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00796     sq_pop(vm, 3);
    00797
    00798     /* Get the 'real' instance of this class */
    00799     sq_getinstanceup(vm, 1, &real_instance, 0);
    00800     /* Get the real function pointer */
    00801     sq_getuserdata(vm, nparam, &ptr, 0);
    00802     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00803     /* Remove the userdata from the stack */
    00804     sq_pop(vm, 1);
    00805
    00806     /* Call the function, which its only param is always the VM */
    00807     return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
    00808   }
    00809
    00815   template <typename Tcls, typename Tmethod>
    00816   inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
    00817   {
    00818     /* Find the amount of params we got */
    00819     int nparam = sq_gettop(vm);
    00820     SQUserPointer ptr = NULL;
    00821
    00822     /* Get the real function pointer */
    00823     sq_getuserdata(vm, nparam, &ptr, 0);
    00824
    00825     try {
    00826       /* Delegate it to a template that can handle this specific function */
    00827       return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
    00828     } catch (SQInteger e) {
    00829       return e;
    00830     }
    00831   }
    00832
    00833
    00839   template <typename Tcls, typename Tmethod>
    00840   inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
    00841   {
    00842     /* Find the amount of params we got */
    00843     int nparam = sq_gettop(vm);
    00844     SQUserPointer ptr = NULL;
    00845
    00846     /* Get the real function pointer */
    00847     sq_getuserdata(vm, nparam, &ptr, 0);
    00848     /* Remove the userdata from the stack */
    00849     sq_pop(vm, 1);
    00850
    00851     /* Call the function, which its only param is always the VM */
    00852     return (SQInteger)(*(*(Tmethod *)ptr))(vm);
    00853   }
    00854
    00859   template <typename Tcls>
    00860   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
    00861   {
    00862     /* Remove the real instance too */
    00863     if (p != NULL) ((Tcls *)p)->Release();
    00864     return 0;
    00865   }
    00866
    00872   template <typename Tcls, typename Tmethod, int Tnparam>
    00873   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
    00874   {
    00875     try {
    00876       /* Create the real instance */
    00877       Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
    00878       sq_setinstanceup(vm, -Tnparam, instance);
    00879       sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
    00880       instance->AddRef();
    00881       return 0;
    00882     } catch (SQInteger e) {
    00883       return e;
    00884     }
    00885   }
    00886
    00891   template <typename Tcls>
    00892   inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
    00893   {
    00894     try {
    00895       /* Find the amount of params we got */
    00896       int nparam = sq_gettop(vm);
    00897
    00898       /* Create the real instance */
    00899       Tcls *instance = new Tcls(vm);
    00900       sq_setinstanceup(vm, -nparam, instance);
    00901       sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
    00902       instance->AddRef();
    00903       return 0;
    00904     } catch (SQInteger e) {
    00905       return e;
    00906     }
    00907   }
    00908
    00909 } // namespace SQConvert
    00910
    00911 #endif /* SQUIRREL_HELPER_HPP */