# squirrel_helper.hpp

Go to the documentation of this file.

    00001 /* $Id: squirrel_helper.hpp 22886 2011-09-03 18:56:34Z frosch $ */
    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/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   /* functions */
    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   /* methods */
    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     /* Sanity check of the size. */
    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     /* Find the amount of params we got */
    00759     int nparam = sq_gettop(vm);
    00760     SQUserPointer ptr = NULL;
    00761     SQUserPointer real_instance = NULL;
    00762     HSQOBJECT instance;
    00763
    00764     /* Get the 'SQ' instance of this class */
    00765     Squirrel::GetInstance(vm, &instance);
    00766
    00767     /* Protect against calls to a non-static method in a static way */
    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     /* Get the 'real' instance of this class */
    00776     sq_getinstanceup(vm, 1, &real_instance, 0);
    00777     /* Get the real function pointer */
    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     /* Remove the userdata from the stack */
    00781     sq_pop(vm, 1);
    00782
    00783     try {
    00784       /* Delegate it to a template that can handle this specific function */
    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     /* Find the amount of params we got */
    00801     int nparam = sq_gettop(vm);
    00802     SQUserPointer ptr = NULL;
    00803     SQUserPointer real_instance = NULL;
    00804     HSQOBJECT instance;
    00805
    00806     /* Get the 'SQ' instance of this class */
    00807     Squirrel::GetInstance(vm, &instance);
    00808
    00809     /* Protect against calls to a non-static method in a static way */
    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     /* Get the 'real' instance of this class */
    00818     sq_getinstanceup(vm, 1, &real_instance, 0);
    00819     /* Get the real function pointer */
    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     /* Remove the userdata from the stack */
    00823     sq_pop(vm, 1);
    00824
    00825     /* Call the function, which its only param is always the VM */
    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     /* Find the amount of params we got */
    00838     int nparam = sq_gettop(vm);
    00839     SQUserPointer ptr = NULL;
    00840
    00841     /* Get the real function pointer */
    00842     sq_getuserdata(vm, nparam, &ptr, 0);
    00843
    00844     try {
    00845       /* Delegate it to a template that can handle this specific function */
    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     /* Remove the real instance too */
    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     /* Find the amount of params we got */
    00874     int nparam = sq_gettop(vm);
    00875
    00876     try {
    00877       /* Create the real instance */
    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 } // namespace SQConvert
    00890
    00891 #endif /* SQUIRREL_HELPER_HPP */