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 
00022 template <class CL, ScriptType ST> const char *GetClassName();
00023 
00027 namespace SQConvert {
00033   struct SQAutoFreePointers : SmallVector<void *, 1> {
00034     ~SQAutoFreePointers()
00035     {
00036       for (uint i = 0; i < this->items; i++) free(this->data[i]);
00037     }
00038   };
00039 
00040   template <bool Y> struct YesT {
00041     static const bool Yes = Y;
00042     static const bool No = !Y;
00043   };
00044 
00048   template <typename T> struct IsVoidT : YesT<false> {};
00049   template <> struct IsVoidT<void> : YesT<true> {};
00050 
00054   template <typename Tfunc> struct HasVoidReturnT;
00055   /* functions */
00056   template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
00057   template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
00058   template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
00059   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
00060   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
00061   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
00062   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> {};
00063   /* methods */
00064   template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
00065   template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
00066   template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
00067   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
00068   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
00069   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> {};
00070   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> {};
00071 
00072 
00076   template <typename T> class ForceType { };
00077 
00081   template <typename T> static int Return(HSQUIRRELVM vm, T t);
00082 
00083   template <> inline int Return<uint8>       (HSQUIRRELVM vm, uint8 res)       { sq_pushinteger(vm, (int32)res); return 1; }
00084   template <> inline int Return<uint16>      (HSQUIRRELVM vm, uint16 res)      { sq_pushinteger(vm, (int32)res); return 1; }
00085   template <> inline int Return<uint32>      (HSQUIRRELVM vm, uint32 res)      { sq_pushinteger(vm, (int32)res); return 1; }
00086   template <> inline int Return<int8>        (HSQUIRRELVM vm, int8 res)        { sq_pushinteger(vm, res); return 1; }
00087   template <> inline int Return<int16>       (HSQUIRRELVM vm, int16 res)       { sq_pushinteger(vm, res); return 1; }
00088   template <> inline int Return<int32>       (HSQUIRRELVM vm, int32 res)       { sq_pushinteger(vm, res); return 1; }
00089   template <> inline int Return<int64>       (HSQUIRRELVM vm, int64 res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
00090   template <> inline int Return<Money>       (HSQUIRRELVM vm, Money res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
00091   template <> inline int Return<bool>        (HSQUIRRELVM vm, bool res)        { sq_pushbool   (vm, res); return 1; }
00092   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; }
00093   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; }
00094   template <> inline int Return<void *>      (HSQUIRRELVM vm, void *res)       { sq_pushuserpointer(vm, res); return 1; }
00095   template <> inline int Return<HSQOBJECT>   (HSQUIRRELVM vm, HSQOBJECT res)   { sq_pushobject(vm, res); return 1; }
00096 
00100   template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
00101 
00102   template <> inline uint8       GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00103   template <> inline uint16      GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00104   template <> inline uint32      GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00105   template <> inline int8        GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00106   template <> inline int16       GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00107   template <> inline int32       GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
00108   template <> inline bool        GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool        tmp; sq_getbool       (vm, index, &tmp); return tmp != 0; }
00109   template <> inline void       *GetParam(ForceType<void *>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
00110   template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
00111   {
00112     /* Convert what-ever there is as parameter to a string */
00113     sq_tostring(vm, index);
00114 
00115     const SQChar *tmp;
00116     sq_getstring(vm, -1, &tmp);
00117     char *tmp_str = strdup(SQ2OTTD(tmp));
00118     sq_poptop(vm);
00119     *ptr->Append() = (void *)tmp_str;
00120     str_validate(tmp_str, tmp_str + strlen(tmp_str));
00121     return tmp_str;
00122   }
00123 
00124   template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
00125   {
00126     /* Sanity check of the size. */
00127     if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, _SC("an array used as parameter to a function is too large"));
00128 
00129     SQObject obj;
00130     sq_getstackobj(vm, index, &obj);
00131     sq_pushobject(vm, obj);
00132     sq_pushnull(vm);
00133 
00134     SmallVector<int32, 2> data;
00135 
00136     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
00137       SQInteger tmp;
00138       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
00139         *data.Append() = (int32)tmp;
00140       } else {
00141         sq_pop(vm, 4);
00142         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
00143       }
00144 
00145       sq_pop(vm, 2);
00146     }
00147     sq_pop(vm, 2);
00148 
00149     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
00150     arr->size = data.Length();
00151     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
00152 
00153     *ptr->Append() = arr;
00154     return arr;
00155   }
00156 
00162   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
00163 
00167   template <typename Tretval>
00168   struct HelperT<Tretval (*)(), false> {
00169     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00170     {
00171       return Return(vm, (*func)());
00172     }
00173   };
00174 
00178   template <typename Tretval>
00179   struct HelperT<Tretval (*)(), true> {
00180     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00181     {
00182       (*func)();
00183       return 0;
00184     }
00185   };
00186 
00190   template <class Tcls, typename Tretval>
00191   struct HelperT<Tretval (Tcls::*)(), false> {
00192     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00193     {
00194       return Return(vm, (instance->*func)());
00195     }
00196   };
00197 
00201   template <class Tcls, typename Tretval>
00202   struct HelperT<Tretval (Tcls::*)(), true> {
00203     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00204     {
00205       (instance->*func)();
00206       return 0;
00207     }
00208 
00209     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00210     {
00211       return new Tcls();
00212     }
00213   };
00214 
00218   template <typename Tretval, typename Targ1>
00219   struct HelperT<Tretval (*)(Targ1), false> {
00220     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00221     {
00222       SQAutoFreePointers ptr;
00223       Tretval ret = (*func)(
00224         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00225       );
00226       return Return(vm, ret);
00227     }
00228   };
00229 
00233   template <typename Tretval, typename Targ1>
00234   struct HelperT<Tretval (*)(Targ1), true> {
00235     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00236     {
00237       SQAutoFreePointers ptr;
00238       (*func)(
00239         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00240       );
00241       return 0;
00242     }
00243   };
00244 
00248   template <class Tcls, typename Tretval, typename Targ1>
00249   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
00250     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00251     {
00252       SQAutoFreePointers ptr;
00253       Tretval ret = (instance->*func)(
00254         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00255       );
00256       return Return(vm, ret);
00257     }
00258   };
00259 
00263   template <class Tcls, typename Tretval, typename Targ1>
00264   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
00265     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00266     {
00267       SQAutoFreePointers ptr;
00268       (instance->*func)(
00269         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00270       );
00271       return 0;
00272     }
00273 
00274     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00275     {
00276       SQAutoFreePointers ptr;
00277       Tcls *inst = new Tcls(
00278         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00279       );
00280 
00281       return inst;
00282     }
00283   };
00284 
00288   template <typename Tretval, typename Targ1, typename Targ2>
00289   struct HelperT<Tretval (*)(Targ1, Targ2), false> {
00290     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
00291     {
00292       SQAutoFreePointers ptr;
00293       Tretval ret = (*func)(
00294         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00295         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00296       );
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       return 0;
00314     }
00315   };
00316 
00320   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
00321   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
00322     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00323     {
00324       SQAutoFreePointers ptr;
00325       Tretval ret = (instance->*func)(
00326         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00327         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00328       );
00329       return Return(vm, ret);
00330     }
00331   };
00332 
00336   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
00337   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
00338     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00339     {
00340       SQAutoFreePointers ptr;
00341       (instance->*func)(
00342         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00343         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00344       );
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       return Return(vm, ret);
00374     }
00375   };
00376 
00380   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00381   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
00382     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00383     {
00384       SQAutoFreePointers ptr;
00385       (*func)(
00386         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00387         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00388         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00389       );
00390       return 0;
00391     }
00392   };
00393 
00397   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00398   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
00399     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00400     {
00401       SQAutoFreePointers ptr;
00402       Tretval ret = (instance->*func)(
00403         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00404         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00405         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00406       );
00407       return Return(vm, ret);
00408     }
00409   };
00410 
00414   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00415   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
00416     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00417     {
00418       SQAutoFreePointers ptr;
00419       (instance->*func)(
00420         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00421         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00422         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00423       );
00424       return 0;
00425     }
00426 
00427     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00428     {
00429       SQAutoFreePointers ptr;
00430       Tcls *inst = new Tcls(
00431         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00432         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00433         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00434       );
00435 
00436       return inst;
00437     }
00438   };
00439 
00443   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00444   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
00445     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00446     {
00447       SQAutoFreePointers ptr;
00448       Tretval ret = (*func)(
00449         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00450         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00451         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00452         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00453       );
00454       return Return(vm, ret);
00455     }
00456   };
00457 
00461   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00462   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
00463     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00464     {
00465       SQAutoFreePointers ptr;
00466       (*func)(
00467         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00468         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00469         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00470         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00471       );
00472       return 0;
00473     }
00474   };
00475 
00479   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00480   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
00481     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00482     {
00483       SQAutoFreePointers ptr;
00484       Tretval ret = (instance->*func)(
00485         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00486         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00487         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00488         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00489       );
00490       return Return(vm, ret);
00491     }
00492   };
00493 
00497   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00498   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
00499     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00500     {
00501       SQAutoFreePointers ptr;
00502       (instance->*func)(
00503         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00504         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00505         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00506         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00507       );
00508       return 0;
00509     }
00510 
00511     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00512     {
00513       SQAutoFreePointers ptr;
00514       Tcls *inst = new Tcls(
00515         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00516         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00517         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00518         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00519       );
00520 
00521       return inst;
00522     }
00523   };
00524 
00528   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00529   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00530     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00531     {
00532       SQAutoFreePointers ptr;
00533       Tretval ret = (*func)(
00534         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00535         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00536         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00537         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00538         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00539       );
00540       return Return(vm, ret);
00541     }
00542   };
00543 
00547   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00548   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00549     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00550     {
00551       SQAutoFreePointers ptr;
00552       (*func)(
00553         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00554         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00555         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00556         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00557         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00558       );
00559       return 0;
00560     }
00561   };
00562 
00566   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00567   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00568     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00569     {
00570       SQAutoFreePointers ptr;
00571       Tretval ret = (instance->*func)(
00572         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00573         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00574         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00575         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00576         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00577       );
00578       return Return(vm, ret);
00579     }
00580   };
00581 
00585   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00586   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00587     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00588     {
00589       SQAutoFreePointers ptr;
00590       (instance->*func)(
00591         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00592         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00593         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00594         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00595         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00596       );
00597       return 0;
00598     }
00599 
00600     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00601     {
00602       SQAutoFreePointers ptr;
00603       Tcls *inst = new Tcls(
00604         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00605         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00606         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00607         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00608         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00609       );
00610 
00611       return inst;
00612     }
00613   };
00614 
00618   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00619   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00620     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00621     {
00622       SQAutoFreePointers ptr;
00623       Tretval ret = (*func)(
00624         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00625         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00626         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00627         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00628         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00629         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00630         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00631         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00632         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00633         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00634       );
00635       return Return(vm, ret);
00636     }
00637   };
00638 
00642   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00643   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00644     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00645     {
00646       SQAutoFreePointers ptr;
00647       (*func)(
00648         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00649         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00650         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00651         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00652         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00653         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00654         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00655         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00656         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00657         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00658       );
00659       return 0;
00660     }
00661   };
00662 
00666   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>
00667   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00668     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00669     {
00670       SQAutoFreePointers ptr;
00671       Tretval ret = (instance->*func)(
00672         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00673         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00674         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00675         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00676         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00677         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00678         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00679         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00680         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00681         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00682       );
00683       return Return(vm, ret);
00684     }
00685   };
00686 
00690   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>
00691   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00692     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00693     {
00694       SQAutoFreePointers ptr;
00695       (instance->*func)(
00696         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00697         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00698         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00699         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00700         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00701         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00702         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00703         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00704         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00705         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00706       );
00707       return 0;
00708     }
00709 
00710     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00711     {
00712       SQAutoFreePointers ptr;
00713       Tcls *inst = new Tcls(
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 
00726       return inst;
00727     }
00728   };
00729 
00730 
00736   template <typename Tcls, typename Tmethod, ScriptType Ttype>
00737   inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
00738   {
00739     /* Find the amount of params we got */
00740     int nparam = sq_gettop(vm);
00741     SQUserPointer ptr = NULL;
00742     SQUserPointer real_instance = NULL;
00743     HSQOBJECT instance;
00744 
00745     /* Get the 'SQ' instance of this class */
00746     Squirrel::GetInstance(vm, &instance);
00747 
00748     /* Protect against calls to a non-static method in a static way */
00749     sq_pushroottable(vm);
00750     const char *className = GetClassName<Tcls, Ttype>();
00751     sq_pushstring(vm, OTTD2SQ(className), -1);
00752     sq_get(vm, -2);
00753     sq_pushobject(vm, instance);
00754     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00755     sq_pop(vm, 3);
00756 
00757     /* Get the 'real' instance of this class */
00758     sq_getinstanceup(vm, 1, &real_instance, 0);
00759     /* Get the real function pointer */
00760     sq_getuserdata(vm, nparam, &ptr, 0);
00761     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00762     /* Remove the userdata from the stack */
00763     sq_pop(vm, 1);
00764 
00765     try {
00766       /* Delegate it to a template that can handle this specific function */
00767       return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
00768     } catch (SQInteger e) {
00769       return e;
00770     }
00771   }
00772 
00778   template <typename Tcls, typename Tmethod, ScriptType Ttype>
00779   inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
00780   {
00781     /* Find the amount of params we got */
00782     int nparam = sq_gettop(vm);
00783     SQUserPointer ptr = NULL;
00784     SQUserPointer real_instance = NULL;
00785     HSQOBJECT instance;
00786 
00787     /* Get the 'SQ' instance of this class */
00788     Squirrel::GetInstance(vm, &instance);
00789 
00790     /* Protect against calls to a non-static method in a static way */
00791     sq_pushroottable(vm);
00792     const char *className = GetClassName<Tcls, Ttype>();
00793     sq_pushstring(vm, OTTD2SQ(className), -1);
00794     sq_get(vm, -2);
00795     sq_pushobject(vm, instance);
00796     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00797     sq_pop(vm, 3);
00798 
00799     /* Get the 'real' instance of this class */
00800     sq_getinstanceup(vm, 1, &real_instance, 0);
00801     /* Get the real function pointer */
00802     sq_getuserdata(vm, nparam, &ptr, 0);
00803     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00804     /* Remove the userdata from the stack */
00805     sq_pop(vm, 1);
00806 
00807     /* Call the function, which its only param is always the VM */
00808     return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
00809   }
00810 
00816   template <typename Tcls, typename Tmethod>
00817   inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
00818   {
00819     /* Find the amount of params we got */
00820     int nparam = sq_gettop(vm);
00821     SQUserPointer ptr = NULL;
00822 
00823     /* Get the real function pointer */
00824     sq_getuserdata(vm, nparam, &ptr, 0);
00825 
00826     try {
00827       /* Delegate it to a template that can handle this specific function */
00828       return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
00829     } catch (SQInteger e) {
00830       return e;
00831     }
00832   }
00833 
00834 
00840   template <typename Tcls, typename Tmethod>
00841   inline SQInteger DefSQAdvancedStaticCallback(HSQUIRRELVM vm)
00842   {
00843     /* Find the amount of params we got */
00844     int nparam = sq_gettop(vm);
00845     SQUserPointer ptr = NULL;
00846 
00847     /* Get the real function pointer */
00848     sq_getuserdata(vm, nparam, &ptr, 0);
00849     /* Remove the userdata from the stack */
00850     sq_pop(vm, 1);
00851 
00852     /* Call the function, which its only param is always the VM */
00853     return (SQInteger)(*(*(Tmethod *)ptr))(vm);
00854   }
00855 
00860   template <typename Tcls>
00861   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
00862   {
00863     /* Remove the real instance too */
00864     if (p != NULL) ((Tcls *)p)->Release();
00865     return 0;
00866   }
00867 
00873   template <typename Tcls, typename Tmethod, int Tnparam>
00874   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM 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       return e;
00885     }
00886   }
00887 
00892   template <typename Tcls>
00893   inline SQInteger DefSQAdvancedConstructorCallback(HSQUIRRELVM vm)
00894   {
00895     try {
00896       /* Find the amount of params we got */
00897       int nparam = sq_gettop(vm);
00898 
00899       /* Create the real instance */
00900       Tcls *instance = new Tcls(vm);
00901       sq_setinstanceup(vm, -nparam, instance);
00902       sq_setreleasehook(vm, -nparam, DefSQDestructorCallback<Tcls>);
00903       instance->AddRef();
00904       return 0;
00905     } catch (SQInteger e) {
00906       return e;
00907     }
00908   }
00909 
00910 } // namespace SQConvert
00911 
00912 #endif /* SQUIRREL_HELPER_HPP */