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/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 */