# squirrel_helper.hpp

Go to the documentation of this file.

    00001 /* $Id$ */
    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     SQObject obj;
    00122     sq_getstackobj(vm, index, &obj);
    00123     sq_pushobject(vm, obj);
    00124     sq_pushnull(vm);
    00125
    00126     SmallVector<int32, 2> data;
    00127
    00128     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
    00129       SQInteger tmp;
    00130       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
    00131         *data.Append() = (int32)tmp;
    00132       } else {
    00133         sq_pop(vm, 4);
    00134         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
    00135       }
    00136
    00137       sq_pop(vm, 2);
    00138     }
    00139     sq_pop(vm, 2);
    00140
    00141     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
    00142     arr->size = data.Length();
    00143     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
    00144
    00145     *ptr->Append() = arr;
    00146     return arr;
    00147   }
    00148
    00154   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
    00155
    00159   template <typename Tretval>
    00160   struct HelperT<Tretval (*)(), false> {
    00161     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00162     {
    00163       return Return(vm, (*func)());
    00164     }
    00165   };
    00166
    00170   template <typename Tretval>
    00171   struct HelperT<Tretval (*)(), true> {
    00172     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00173     {
    00174       (*func)();
    00175       return 0;
    00176     }
    00177   };
    00178
    00182   template <class Tcls, typename Tretval>
    00183   struct HelperT<Tretval (Tcls::*)(), false> {
    00184     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00185     {
    00186       return Return(vm, (instance->*func)());
    00187     }
    00188   };
    00189
    00193   template <class Tcls, typename Tretval>
    00194   struct HelperT<Tretval (Tcls::*)(), true> {
    00195     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00196     {
    00197       (instance->*func)();
    00198       return 0;
    00199     }
    00200
    00201     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00202     {
    00203       return new Tcls();
    00204     }
    00205   };
    00206
    00210   template <typename Tretval, typename Targ1>
    00211   struct HelperT<Tretval (*)(Targ1), false> {
    00212     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00213     {
    00214       SQAutoFreePointers ptr;
    00215       Tretval ret = (*func)(
    00216         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00217       );
    00218       sq_pop(vm, 1);
    00219       return Return(vm, ret);
    00220     }
    00221   };
    00222
    00226   template <typename Tretval, typename Targ1>
    00227   struct HelperT<Tretval (*)(Targ1), true> {
    00228     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00229     {
    00230       SQAutoFreePointers ptr;
    00231       (*func)(
    00232         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00233       );
    00234       sq_pop(vm, 1);
    00235       return 0;
    00236     }
    00237   };
    00238
    00242   template <class Tcls, typename Tretval, typename Targ1>
    00243   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
    00244     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00245     {
    00246       SQAutoFreePointers ptr;
    00247       Tretval ret = (instance->*func)(
    00248         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00249       );
    00250       sq_pop(vm, 1);
    00251       return Return(vm, ret);
    00252     }
    00253   };
    00254
    00258   template <class Tcls, typename Tretval, typename Targ1>
    00259   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
    00260     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00261     {
    00262       SQAutoFreePointers ptr;
    00263       (instance->*func)(
    00264         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00265       );
    00266       sq_pop(vm, 1);
    00267       return 0;
    00268     }
    00269
    00270     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00271     {
    00272       SQAutoFreePointers ptr;
    00273       Tcls *inst = new Tcls(
    00274         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00275       );
    00276
    00277       return inst;
    00278     }
    00279   };
    00280
    00284   template <typename Tretval, typename Targ1, typename Targ2>
    00285   struct HelperT<Tretval (*)(Targ1, Targ2), false> {
    00286     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00287     {
    00288       SQAutoFreePointers ptr;
    00289       Tretval ret = (*func)(
    00290         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00291         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00292       );
    00293       sq_pop(vm, 2);
    00294       return Return(vm, ret);
    00295     }
    00296   };
    00297
    00301   template <typename Tretval, typename Targ1, typename Targ2>
    00302   struct HelperT<Tretval (*)(Targ1, Targ2), true> {
    00303     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00304     {
    00305       SQAutoFreePointers ptr;
    00306       (*func)(
    00307         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00308         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00309       );
    00310       sq_pop(vm, 2);
    00311       return 0;
    00312     }
    00313   };
    00314
    00318   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00319   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
    00320     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00321     {
    00322       SQAutoFreePointers ptr;
    00323       Tretval ret = (instance->*func)(
    00324         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00325         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00326       );
    00327       sq_pop(vm, 2);
    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       sq_pop(vm, 2);
    00345       return 0;
    00346     }
    00347
    00348     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00349     {
    00350       SQAutoFreePointers ptr;
    00351       Tcls *inst = new Tcls(
    00352         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00353         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00354       );
    00355
    00356       return inst;
    00357     }
    00358   };
    00359
    00363   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00364   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
    00365     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00366     {
    00367       SQAutoFreePointers ptr;
    00368       Tretval ret = (*func)(
    00369         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00370         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00371         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00372       );
    00373       sq_pop(vm, 3);
    00374       return Return(vm, ret);
    00375     }
    00376   };
    00377
    00381   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00382   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
    00383     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00384     {
    00385       SQAutoFreePointers ptr;
    00386       (*func)(
    00387         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00388         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00389         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00390       );
    00391       sq_pop(vm, 3);
    00392       return 0;
    00393     }
    00394   };
    00395
    00399   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00400   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
    00401     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00402     {
    00403       SQAutoFreePointers ptr;
    00404       Tretval ret = (instance->*func)(
    00405         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00406         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00407         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00408       );
    00409       sq_pop(vm, 3);
    00410       return Return(vm, ret);
    00411     }
    00412   };
    00413
    00417   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00418   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
    00419     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00420     {
    00421       SQAutoFreePointers ptr;
    00422       (instance->*func)(
    00423         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00424         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00425         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00426       );
    00427       sq_pop(vm, 3);
    00428       return 0;
    00429     }
    00430
    00431     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00432     {
    00433       SQAutoFreePointers ptr;
    00434       Tcls *inst = new Tcls(
    00435         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00436         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00437         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00438       );
    00439
    00440       return inst;
    00441     }
    00442   };
    00443
    00447   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00448   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
    00449     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00450     {
    00451       SQAutoFreePointers ptr;
    00452       Tretval ret = (*func)(
    00453         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00454         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00455         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00456         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00457       );
    00458       sq_pop(vm, 4);
    00459       return Return(vm, ret);
    00460     }
    00461   };
    00462
    00466   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00467   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
    00468     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00469     {
    00470       SQAutoFreePointers ptr;
    00471       (*func)(
    00472         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00473         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00474         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00475         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00476       );
    00477       sq_pop(vm, 4);
    00478       return 0;
    00479     }
    00480   };
    00481
    00485   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00486   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
    00487     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00488     {
    00489       SQAutoFreePointers ptr;
    00490       Tretval ret = (instance->*func)(
    00491         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00492         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00493         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00494         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00495       );
    00496       sq_pop(vm, 4);
    00497       return Return(vm, ret);
    00498     }
    00499   };
    00500
    00504   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00505   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
    00506     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00507     {
    00508       SQAutoFreePointers ptr;
    00509       (instance->*func)(
    00510         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00511         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00512         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00513         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00514       );
    00515       sq_pop(vm, 4);
    00516       return 0;
    00517     }
    00518
    00519     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00520     {
    00521       SQAutoFreePointers ptr;
    00522       Tcls *inst = new Tcls(
    00523         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00524         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00525         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00526         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00527       );
    00528
    00529       return inst;
    00530     }
    00531   };
    00532
    00536   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00537   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00538     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00539     {
    00540       SQAutoFreePointers ptr;
    00541       Tretval ret = (*func)(
    00542         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00543         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00544         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00545         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00546         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00547       );
    00548       sq_pop(vm, 5);
    00549       return Return(vm, ret);
    00550     }
    00551   };
    00552
    00556   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00557   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00558     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00559     {
    00560       SQAutoFreePointers ptr;
    00561       (*func)(
    00562         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00563         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00564         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00565         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00566         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00567       );
    00568       sq_pop(vm, 5);
    00569       return 0;
    00570     }
    00571   };
    00572
    00576   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00577   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00578     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00579     {
    00580       SQAutoFreePointers ptr;
    00581       Tretval ret = (instance->*func)(
    00582         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00583         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00584         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00585         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00586         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00587       );
    00588       sq_pop(vm, 5);
    00589       return Return(vm, ret);
    00590     }
    00591   };
    00592
    00596   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00597   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00598     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00599     {
    00600       SQAutoFreePointers ptr;
    00601       (instance->*func)(
    00602         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00603         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00604         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00605         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00606         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00607       );
    00608       sq_pop(vm, 5);
    00609       return 0;
    00610     }
    00611
    00612     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00613     {
    00614       SQAutoFreePointers ptr;
    00615       Tcls *inst = new Tcls(
    00616         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00617         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00618         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00619         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00620         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00621       );
    00622
    00623       return inst;
    00624     }
    00625   };
    00626
    00630   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00631   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00632     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00633     {
    00634       SQAutoFreePointers ptr;
    00635       Tretval ret = (*func)(
    00636         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00637         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00638         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00639         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00640         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00641         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00642         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00643         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00644         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00645         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00646       );
    00647       sq_pop(vm, 10);
    00648       return Return(vm, ret);
    00649     }
    00650   };
    00651
    00655   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00656   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00657     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00658     {
    00659       SQAutoFreePointers ptr;
    00660       (*func)(
    00661         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00662         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00663         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00664         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00665         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00666         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00667         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00668         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00669         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00670         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00671       );
    00672       sq_pop(vm, 10);
    00673       return 0;
    00674     }
    00675   };
    00676
    00680   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>
    00681   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00682     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00683     {
    00684       SQAutoFreePointers ptr;
    00685       Tretval ret = (instance->*func)(
    00686         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00687         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00688         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00689         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00690         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00691         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00692         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00693         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00694         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00695         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00696       );
    00697       sq_pop(vm, 10);
    00698       return Return(vm, ret);
    00699     }
    00700   };
    00701
    00705   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>
    00706   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00707     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00708     {
    00709       SQAutoFreePointers ptr;
    00710       (instance->*func)(
    00711         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00712         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00713         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00714         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00715         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00716         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00717         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00718         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00719         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00720         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00721       );
    00722       sq_pop(vm, 10);
    00723       return 0;
    00724     }
    00725
    00726     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00727     {
    00728       SQAutoFreePointers ptr;
    00729       Tcls *inst = new Tcls(
    00730         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00731         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00732         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00733         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00734         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00735         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00736         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00737         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00738         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00739         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00740       );
    00741
    00742       return inst;
    00743     }
    00744   };
    00745
    00746
    00752   template <typename Tcls, typename Tmethod>
    00753   inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
    00754   {
    00755     /* Find the amount of params we got */
    00756     int nparam = sq_gettop(vm);
    00757     SQUserPointer ptr = NULL;
    00758     SQUserPointer real_instance = NULL;
    00759     HSQOBJECT instance;
    00760
    00761     /* Get the 'SQ' instance of this class */
    00762     Squirrel::GetInstance(vm, &instance);
    00763
    00764     /* Protect against calls to a non-static method in a static way */
    00765     sq_pushroottable(vm);
    00766     sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
    00767     sq_get(vm, -2);
    00768     sq_pushobject(vm, instance);
    00769     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00770     sq_pop(vm, 3);
    00771
    00772     /* Get the 'real' instance of this class */
    00773     sq_getinstanceup(vm, 1, &real_instance, 0);
    00774     /* Get the real function pointer */
    00775     sq_getuserdata(vm, nparam, &ptr, 0);
    00776     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00777     /* Remove the userdata from the stack */
    00778     sq_pop(vm, 1);
    00779
    00780     try {
    00781       /* Delegate it to a template that can handle this specific function */
    00782       return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
    00783     } catch (SQInteger e) {
    00784       sq_pop(vm, nparam);
    00785       return e;
    00786     }
    00787   }
    00788
    00794   template <typename Tcls, typename Tmethod>
    00795   inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
    00796   {
    00797     /* Find the amount of params we got */
    00798     int nparam = sq_gettop(vm);
    00799     SQUserPointer ptr = NULL;
    00800     SQUserPointer real_instance = NULL;
    00801     HSQOBJECT instance;
    00802
    00803     /* Get the 'SQ' instance of this class */
    00804     Squirrel::GetInstance(vm, &instance);
    00805
    00806     /* Protect against calls to a non-static method in a static way */
    00807     sq_pushroottable(vm);
    00808     sq_pushstring(vm, OTTD2SQ(Tcls::GetClassName()), -1);
    00809     sq_get(vm, -2);
    00810     sq_pushobject(vm, instance);
    00811     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00812     sq_pop(vm, 3);
    00813
    00814     /* Get the 'real' instance of this class */
    00815     sq_getinstanceup(vm, 1, &real_instance, 0);
    00816     /* Get the real function pointer */
    00817     sq_getuserdata(vm, nparam, &ptr, 0);
    00818     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00819     /* Remove the userdata from the stack */
    00820     sq_pop(vm, 1);
    00821
    00822     /* Call the function, which its only param is always the VM */
    00823     return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
    00824   }
    00825
    00831   template <typename Tcls, typename Tmethod>
    00832   inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
    00833   {
    00834     /* Find the amount of params we got */
    00835     int nparam = sq_gettop(vm);
    00836     SQUserPointer ptr = NULL;
    00837
    00838     /* Get the real function pointer */
    00839     sq_getuserdata(vm, nparam, &ptr, 0);
    00840
    00841     try {
    00842       /* Delegate it to a template that can handle this specific function */
    00843       return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
    00844     } catch (SQInteger e) {
    00845       sq_pop(vm, nparam);
    00846       return e;
    00847     }
    00848   }
    00849
    00854   template <typename Tcls>
    00855   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
    00856   {
    00857     /* Remove the real instance too */
    00858     if (p != NULL) ((Tcls *)p)->Release();
    00859     return 0;
    00860   }
    00861
    00867   template <typename Tcls, typename Tmethod, int Tnparam>
    00868   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
    00869   {
    00870     /* Find the amount of params we got */
    00871     int nparam = sq_gettop(vm);
    00872
    00873     try {
    00874       /* Create the real instance */
    00875       Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
    00876       sq_setinstanceup(vm, -Tnparam, instance);
    00877       sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
    00878       instance->AddRef();
    00879       return 0;
    00880     } catch (SQInteger e) {
    00881       sq_pop(vm, nparam);
    00882       return e;
    00883     }
    00884   }
    00885
    00886 } // namespace SQConvert
    00887
    00888 #endif /* SQUIRREL_HELPER_HPP */