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     sq_tostring(vm, index);
00113     const SQChar *tmp;
00114     sq_getstring(vm, -1, &tmp);
00115     char *tmp_str = strdup(SQ2OTTD(tmp));
00116     sq_poptop(vm);
00117     *ptr->Append() = (void *)tmp_str;
00118     str_validate(tmp_str, tmp_str + strlen(tmp_str));
00119     return tmp_str;
00120   }
00121 
00122   template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
00123   {
00124     /* Sanity check of the size. */
00125     if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, _SC("an array used as parameter to a function is too large"));
00126 
00127     SQObject obj;
00128     sq_getstackobj(vm, index, &obj);
00129     sq_pushobject(vm, obj);
00130     sq_pushnull(vm);
00131 
00132     SmallVector<int32, 2> data;
00133 
00134     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
00135       SQInteger tmp;
00136       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
00137         *data.Append() = (int32)tmp;
00138       } else {
00139         sq_pop(vm, 4);
00140         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
00141       }
00142 
00143       sq_pop(vm, 2);
00144     }
00145     sq_pop(vm, 2);
00146 
00147     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
00148     arr->size = data.Length();
00149     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
00150 
00151     *ptr->Append() = arr;
00152     return arr;
00153   }
00154 
00160   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
00161 
00165   template <typename Tretval>
00166   struct HelperT<Tretval (*)(), false> {
00167     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00168     {
00169       return Return(vm, (*func)());
00170     }
00171   };
00172 
00176   template <typename Tretval>
00177   struct HelperT<Tretval (*)(), true> {
00178     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
00179     {
00180       (*func)();
00181       return 0;
00182     }
00183   };
00184 
00188   template <class Tcls, typename Tretval>
00189   struct HelperT<Tretval (Tcls::*)(), false> {
00190     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00191     {
00192       return Return(vm, (instance->*func)());
00193     }
00194   };
00195 
00199   template <class Tcls, typename Tretval>
00200   struct HelperT<Tretval (Tcls::*)(), true> {
00201     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00202     {
00203       (instance->*func)();
00204       return 0;
00205     }
00206 
00207     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
00208     {
00209       return new Tcls();
00210     }
00211   };
00212 
00216   template <typename Tretval, typename Targ1>
00217   struct HelperT<Tretval (*)(Targ1), false> {
00218     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00219     {
00220       SQAutoFreePointers ptr;
00221       Tretval ret = (*func)(
00222         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00223       );
00224       return Return(vm, ret);
00225     }
00226   };
00227 
00231   template <typename Tretval, typename Targ1>
00232   struct HelperT<Tretval (*)(Targ1), true> {
00233     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
00234     {
00235       SQAutoFreePointers ptr;
00236       (*func)(
00237         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00238       );
00239       return 0;
00240     }
00241   };
00242 
00246   template <class Tcls, typename Tretval, typename Targ1>
00247   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
00248     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00249     {
00250       SQAutoFreePointers ptr;
00251       Tretval ret = (instance->*func)(
00252         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00253       );
00254       return Return(vm, ret);
00255     }
00256   };
00257 
00261   template <class Tcls, typename Tretval, typename Targ1>
00262   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
00263     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00264     {
00265       SQAutoFreePointers ptr;
00266       (instance->*func)(
00267         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00268       );
00269       return 0;
00270     }
00271 
00272     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
00273     {
00274       SQAutoFreePointers ptr;
00275       Tcls *inst = new Tcls(
00276         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
00277       );
00278 
00279       return inst;
00280     }
00281   };
00282 
00286   template <typename Tretval, typename Targ1, typename Targ2>
00287   struct HelperT<Tretval (*)(Targ1, Targ2), false> {
00288     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
00289     {
00290       SQAutoFreePointers ptr;
00291       Tretval ret = (*func)(
00292         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00293         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00294       );
00295       return Return(vm, ret);
00296     }
00297   };
00298 
00302   template <typename Tretval, typename Targ1, typename Targ2>
00303   struct HelperT<Tretval (*)(Targ1, Targ2), true> {
00304     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
00305     {
00306       SQAutoFreePointers ptr;
00307       (*func)(
00308         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00309         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00310       );
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       return Return(vm, ret);
00328     }
00329   };
00330 
00334   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
00335   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
00336     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00337     {
00338       SQAutoFreePointers ptr;
00339       (instance->*func)(
00340         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00341         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00342       );
00343       return 0;
00344     }
00345 
00346     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
00347     {
00348       SQAutoFreePointers ptr;
00349       Tcls *inst = new Tcls(
00350         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00351         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
00352       );
00353 
00354       return inst;
00355     }
00356   };
00357 
00361   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00362   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
00363     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00364     {
00365       SQAutoFreePointers ptr;
00366       Tretval ret = (*func)(
00367         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00368         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00369         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00370       );
00371       return Return(vm, ret);
00372     }
00373   };
00374 
00378   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00379   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
00380     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00381     {
00382       SQAutoFreePointers ptr;
00383       (*func)(
00384         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00385         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00386         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00387       );
00388       return 0;
00389     }
00390   };
00391 
00395   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00396   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
00397     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00398     {
00399       SQAutoFreePointers ptr;
00400       Tretval ret = (instance->*func)(
00401         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00402         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00403         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00404       );
00405       return Return(vm, ret);
00406     }
00407   };
00408 
00412   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
00413   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
00414     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00415     {
00416       SQAutoFreePointers ptr;
00417       (instance->*func)(
00418         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00419         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00420         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00421       );
00422       return 0;
00423     }
00424 
00425     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
00426     {
00427       SQAutoFreePointers ptr;
00428       Tcls *inst = new Tcls(
00429         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00430         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00431         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
00432       );
00433 
00434       return inst;
00435     }
00436   };
00437 
00441   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00442   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
00443     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00444     {
00445       SQAutoFreePointers ptr;
00446       Tretval ret = (*func)(
00447         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00448         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00449         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00450         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00451       );
00452       return Return(vm, ret);
00453     }
00454   };
00455 
00459   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00460   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
00461     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00462     {
00463       SQAutoFreePointers ptr;
00464       (*func)(
00465         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00466         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00467         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00468         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00469       );
00470       return 0;
00471     }
00472   };
00473 
00477   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00478   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
00479     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00480     {
00481       SQAutoFreePointers ptr;
00482       Tretval ret = (instance->*func)(
00483         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00484         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00485         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00486         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00487       );
00488       return Return(vm, ret);
00489     }
00490   };
00491 
00495   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
00496   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
00497     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00498     {
00499       SQAutoFreePointers ptr;
00500       (instance->*func)(
00501         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00502         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00503         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00504         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00505       );
00506       return 0;
00507     }
00508 
00509     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
00510     {
00511       SQAutoFreePointers ptr;
00512       Tcls *inst = new Tcls(
00513         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00514         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00515         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00516         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
00517       );
00518 
00519       return inst;
00520     }
00521   };
00522 
00526   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00527   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00528     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00529     {
00530       SQAutoFreePointers ptr;
00531       Tretval ret = (*func)(
00532         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00533         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00534         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00535         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00536         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00537       );
00538       return Return(vm, ret);
00539     }
00540   };
00541 
00545   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00546   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00547     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00548     {
00549       SQAutoFreePointers ptr;
00550       (*func)(
00551         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00552         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00553         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00554         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00555         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00556       );
00557       return 0;
00558     }
00559   };
00560 
00564   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00565   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
00566     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00567     {
00568       SQAutoFreePointers ptr;
00569       Tretval ret = (instance->*func)(
00570         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00571         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00572         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00573         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00574         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00575       );
00576       return Return(vm, ret);
00577     }
00578   };
00579 
00583   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
00584   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
00585     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00586     {
00587       SQAutoFreePointers ptr;
00588       (instance->*func)(
00589         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00590         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00591         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00592         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00593         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
00594       );
00595       return 0;
00596     }
00597 
00598     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
00599     {
00600       SQAutoFreePointers ptr;
00601       Tcls *inst = new Tcls(
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 
00609       return inst;
00610     }
00611   };
00612 
00616   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00617   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00618     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00619     {
00620       SQAutoFreePointers ptr;
00621       Tretval ret = (*func)(
00622         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00623         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00624         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00625         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00626         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00627         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00628         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00629         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00630         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00631         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00632       );
00633       return Return(vm, ret);
00634     }
00635   };
00636 
00640   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
00641   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00642     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00643     {
00644       SQAutoFreePointers ptr;
00645       (*func)(
00646         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00647         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00648         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00649         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00650         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00651         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00652         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00653         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00654         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00655         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00656       );
00657       return 0;
00658     }
00659   };
00660 
00664   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>
00665   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
00666     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00667     {
00668       SQAutoFreePointers ptr;
00669       Tretval ret = (instance->*func)(
00670         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00671         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00672         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00673         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00674         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00675         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00676         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00677         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00678         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00679         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00680       );
00681       return Return(vm, ret);
00682     }
00683   };
00684 
00688   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>
00689   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
00690     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00691     {
00692       SQAutoFreePointers ptr;
00693       (instance->*func)(
00694         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00695         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00696         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00697         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00698         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00699         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00700         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00701         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00702         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00703         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00704       );
00705       return 0;
00706     }
00707 
00708     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
00709     {
00710       SQAutoFreePointers ptr;
00711       Tcls *inst = new Tcls(
00712         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
00713         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
00714         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
00715         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
00716         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
00717         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
00718         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
00719         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
00720         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
00721         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
00722       );
00723 
00724       return inst;
00725     }
00726   };
00727 
00728 
00734   template <typename Tcls, typename Tmethod, ScriptType Ttype>
00735   inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
00736   {
00737     /* Find the amount of params we got */
00738     int nparam = sq_gettop(vm);
00739     SQUserPointer ptr = NULL;
00740     SQUserPointer real_instance = NULL;
00741     HSQOBJECT instance;
00742 
00743     /* Get the 'SQ' instance of this class */
00744     Squirrel::GetInstance(vm, &instance);
00745 
00746     /* Protect against calls to a non-static method in a static way */
00747     sq_pushroottable(vm);
00748     const char *className = GetClassName<Tcls, Ttype>();
00749     sq_pushstring(vm, OTTD2SQ(className), -1);
00750     sq_get(vm, -2);
00751     sq_pushobject(vm, instance);
00752     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00753     sq_pop(vm, 3);
00754 
00755     /* Get the 'real' instance of this class */
00756     sq_getinstanceup(vm, 1, &real_instance, 0);
00757     /* Get the real function pointer */
00758     sq_getuserdata(vm, nparam, &ptr, 0);
00759     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00760     /* Remove the userdata from the stack */
00761     sq_pop(vm, 1);
00762 
00763     try {
00764       /* Delegate it to a template that can handle this specific function */
00765       return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
00766     } catch (SQInteger e) {
00767       return e;
00768     }
00769   }
00770 
00776   template <typename Tcls, typename Tmethod, ScriptType Ttype>
00777   inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
00778   {
00779     /* Find the amount of params we got */
00780     int nparam = sq_gettop(vm);
00781     SQUserPointer ptr = NULL;
00782     SQUserPointer real_instance = NULL;
00783     HSQOBJECT instance;
00784 
00785     /* Get the 'SQ' instance of this class */
00786     Squirrel::GetInstance(vm, &instance);
00787 
00788     /* Protect against calls to a non-static method in a static way */
00789     sq_pushroottable(vm);
00790     const char *className = GetClassName<Tcls, Ttype>();
00791     sq_pushstring(vm, OTTD2SQ(className), -1);
00792     sq_get(vm, -2);
00793     sq_pushobject(vm, instance);
00794     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
00795     sq_pop(vm, 3);
00796 
00797     /* Get the 'real' instance of this class */
00798     sq_getinstanceup(vm, 1, &real_instance, 0);
00799     /* Get the real function pointer */
00800     sq_getuserdata(vm, nparam, &ptr, 0);
00801     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
00802     /* Remove the userdata from the stack */
00803     sq_pop(vm, 1);
00804 
00805     /* Call the function, which its only param is always the VM */
00806     return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
00807   }
00808 
00814   template <typename Tcls, typename Tmethod>
00815   inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
00816   {
00817     /* Find the amount of params we got */
00818     int nparam = sq_gettop(vm);
00819     SQUserPointer ptr = NULL;
00820 
00821     /* Get the real function pointer */
00822     sq_getuserdata(vm, nparam, &ptr, 0);
00823 
00824     try {
00825       /* Delegate it to a template that can handle this specific function */
00826       return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
00827     } catch (SQInteger e) {
00828       return e;
00829     }
00830   }
00831 
00836   template <typename Tcls>
00837   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
00838   {
00839     /* Remove the real instance too */
00840     if (p != NULL) ((Tcls *)p)->Release();
00841     return 0;
00842   }
00843 
00849   template <typename Tcls, typename Tmethod, int Tnparam>
00850   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
00851   {
00852     try {
00853       /* Create the real instance */
00854       Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
00855       sq_setinstanceup(vm, -Tnparam, instance);
00856       sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
00857       instance->AddRef();
00858       return 0;
00859     } catch (SQInteger e) {
00860       return e;
00861     }
00862   }
00863 
00864 } // namespace SQConvert
00865 
00866 #endif /* SQUIRREL_HELPER_HPP */