# squirrel_helper.hpp

Go to the documentation of this file.

    00001 /* $Id: squirrel_helper.hpp 15316 2009-02-02 13:46:26Z glx $ */
    00002
    00005 #ifndef SQUIRREL_HELPER_HPP
    00006 #define SQUIRREL_HELPER_HPP
    00007
    00008 #include <squirrel.h>
    00009 #include "../core/math_func.hpp"
    00010 #include "../core/smallvec_type.hpp"
    00011 #include "../economy_type.h"
    00012 #include "../string_func.h"
    00013 #include "squirrel_helper_type.hpp"
    00014
    00018 namespace SQConvert {
    00024   struct SQAutoFreePointers : SmallVector<void *, 1> {
    00025     ~SQAutoFreePointers()
    00026     {
    00027       for (uint i = 0; i < this->items; i++) free(this->data[i]);
    00028     }
    00029   };
    00030
    00031   template <bool Y> struct YesT {
    00032     static const bool Yes = Y;
    00033     static const bool No = !Y;
    00034   };
    00035
    00039   template <typename T> struct IsVoidT : YesT<false> {};
    00040   template <> struct IsVoidT<void> : YesT<true> {};
    00041
    00045   template <typename Tfunc> struct HasVoidReturnT;
    00046   /* functions */
    00047   template <typename Tretval> struct HasVoidReturnT<Tretval (*)()> : IsVoidT<Tretval> {};
    00048   template <typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (*)(Targ1)> : IsVoidT<Tretval> {};
    00049   template <typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
    00050   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
    00051   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
    00052   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5> struct HasVoidReturnT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5)> : IsVoidT<Tretval> {};
    00053   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> {};
    00054   /* methods */
    00055   template <class Tcls, typename Tretval> struct HasVoidReturnT<Tretval (Tcls::*)()> : IsVoidT<Tretval> {};
    00056   template <class Tcls, typename Tretval, typename Targ1> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1)> : IsVoidT<Tretval> {};
    00057   template <class Tcls, typename Tretval, typename Targ1, typename Targ2> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2)> : IsVoidT<Tretval> {};
    00058   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3)> : IsVoidT<Tretval> {};
    00059   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4> struct HasVoidReturnT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4)> : IsVoidT<Tretval> {};
    00060   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> {};
    00061   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> {};
    00062
    00063
    00067   template <typename T> class ForceType { };
    00068
    00072   template <typename T> static int Return(HSQUIRRELVM vm, T t);
    00073
    00074   template <> inline int Return<uint8>       (HSQUIRRELVM vm, uint8 res)       { sq_pushinteger(vm, (int32)res); return 1; }
    00075   template <> inline int Return<uint16>      (HSQUIRRELVM vm, uint16 res)      { sq_pushinteger(vm, (int32)res); return 1; }
    00076   template <> inline int Return<uint32>      (HSQUIRRELVM vm, uint32 res)      { sq_pushinteger(vm, (int32)res); return 1; }
    00077   template <> inline int Return<int8>        (HSQUIRRELVM vm, int8 res)        { sq_pushinteger(vm, res); return 1; }
    00078   template <> inline int Return<int16>       (HSQUIRRELVM vm, int16 res)       { sq_pushinteger(vm, res); return 1; }
    00079   template <> inline int Return<int32>       (HSQUIRRELVM vm, int32 res)       { sq_pushinteger(vm, res); return 1; }
    00080   template <> inline int Return<int64>       (HSQUIRRELVM vm, int64 res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
    00081   template <> inline int Return<Money>       (HSQUIRRELVM vm, Money res)       { sq_pushinteger(vm, ClampToI32(res)); return 1; }
    00082   template <> inline int Return<bool>        (HSQUIRRELVM vm, bool res)        { sq_pushbool   (vm, res); return 1; }
    00083   template <> inline int Return<char *>      (HSQUIRRELVM vm, char *res)       { if (res == NULL) sq_pushnull(vm); else {str_validate(res, false, true); sq_pushstring (vm, OTTD2FS(res), strlen(res)); free(res);} return 1; }
    00084   template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else {str_validate((char*)res, false, true); sq_pushstring (vm, OTTD2FS(res), strlen(res));} return 1; }
    00085   template <> inline int Return<void *>      (HSQUIRRELVM vm, void *res)       { sq_pushuserpointer(vm, res); return 1; }
    00086
    00090   template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
    00091
    00092   template <> inline uint8       GetParam(ForceType<uint8>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00093   template <> inline uint16      GetParam(ForceType<uint16>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00094   template <> inline uint32      GetParam(ForceType<uint32>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00095   template <> inline int8        GetParam(ForceType<int8>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00096   template <> inline int16       GetParam(ForceType<int16>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00097   template <> inline int32       GetParam(ForceType<int32>       , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger     tmp; sq_getinteger    (vm, index, &tmp); return tmp; }
    00098   template <> inline bool        GetParam(ForceType<bool>        , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool        tmp; sq_getbool       (vm, index, &tmp); return tmp != 0; }
    00099   template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { const SQChar *tmp; sq_getstring     (vm, index, &tmp); char *tmp_str = strdup(FS2OTTD(tmp)); *ptr->Append() = (void *)tmp_str; return tmp_str; }
    00100   template <> inline void       *GetParam(ForceType<void *>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
    00101
    00102   template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
    00103   {
    00104     SQObject obj;
    00105     sq_getstackobj(vm, index, &obj);
    00106     sq_pushobject(vm, obj);
    00107     sq_pushnull(vm);
    00108
    00109     SmallVector<int32, 2> data;
    00110
    00111     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
    00112       SQInteger tmp;
    00113       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
    00114         *data.Append() = (int32)tmp;
    00115       } else {
    00116         sq_pop(vm, 4);
    00117         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
    00118       }
    00119
    00120       sq_pop(vm, 2);
    00121     }
    00122     sq_pop(vm, 2);
    00123
    00124     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
    00125     arr->size = data.Length();
    00126     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
    00127
    00128     *ptr->Append() = arr;
    00129     return arr;
    00130   }
    00131
    00137   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
    00138
    00142   template <typename Tretval>
    00143   struct HelperT<Tretval (*)(), false> {
    00144     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00145     {
    00146       return Return(vm, (*func)());
    00147     }
    00148   };
    00149
    00153   template <typename Tretval>
    00154   struct HelperT<Tretval (*)(), true> {
    00155     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00156     {
    00157       (*func)();
    00158       return 0;
    00159     }
    00160   };
    00161
    00165   template <class Tcls, typename Tretval>
    00166   struct HelperT<Tretval (Tcls::*)(), false> {
    00167     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00168     {
    00169       return Return(vm, (instance->*func)());
    00170     }
    00171   };
    00172
    00176   template <class Tcls, typename Tretval>
    00177   struct HelperT<Tretval (Tcls::*)(), true> {
    00178     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00179     {
    00180       (instance->*func)();
    00181       return 0;
    00182     }
    00183
    00184     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00185     {
    00186       return new Tcls();
    00187     }
    00188   };
    00189
    00193   template <typename Tretval, typename Targ1>
    00194   struct HelperT<Tretval (*)(Targ1), false> {
    00195     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00196     {
    00197       SQAutoFreePointers ptr;
    00198       Tretval ret = (*func)(
    00199         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00200       );
    00201       sq_pop(vm, 1);
    00202       return Return(vm, ret);
    00203     }
    00204   };
    00205
    00209   template <typename Tretval, typename Targ1>
    00210   struct HelperT<Tretval (*)(Targ1), true> {
    00211     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00212     {
    00213       SQAutoFreePointers ptr;
    00214       (*func)(
    00215         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00216       );
    00217       sq_pop(vm, 1);
    00218       return 0;
    00219     }
    00220   };
    00221
    00225   template <class Tcls, typename Tretval, typename Targ1>
    00226   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
    00227     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00228     {
    00229       SQAutoFreePointers ptr;
    00230       Tretval ret = (instance->*func)(
    00231         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00232       );
    00233       sq_pop(vm, 1);
    00234       return Return(vm, ret);
    00235     }
    00236   };
    00237
    00241   template <class Tcls, typename Tretval, typename Targ1>
    00242   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
    00243     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00244     {
    00245       SQAutoFreePointers ptr;
    00246       (instance->*func)(
    00247         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00248       );
    00249       sq_pop(vm, 1);
    00250       return 0;
    00251     }
    00252
    00253     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00254     {
    00255       SQAutoFreePointers ptr;
    00256       Tcls *inst = new Tcls(
    00257         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00258       );
    00259
    00260       return inst;
    00261     }
    00262   };
    00263
    00267   template <typename Tretval, typename Targ1, typename Targ2>
    00268   struct HelperT<Tretval (*)(Targ1, Targ2), false> {
    00269     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00270     {
    00271       SQAutoFreePointers ptr;
    00272       Tretval ret = (*func)(
    00273         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00274         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00275       );
    00276       sq_pop(vm, 2);
    00277       return Return(vm, ret);
    00278     }
    00279   };
    00280
    00284   template <typename Tretval, typename Targ1, typename Targ2>
    00285   struct HelperT<Tretval (*)(Targ1, Targ2), true> {
    00286     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00287     {
    00288       SQAutoFreePointers ptr;
    00289       (*func)(
    00290         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00291         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00292       );
    00293       sq_pop(vm, 2);
    00294       return 0;
    00295     }
    00296   };
    00297
    00301   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00302   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
    00303     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00304     {
    00305       SQAutoFreePointers ptr;
    00306       Tretval ret = (instance->*func)(
    00307         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00308         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00309       );
    00310       sq_pop(vm, 2);
    00311       return Return(vm, ret);
    00312     }
    00313   };
    00314
    00318   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00319   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
    00320     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00321     {
    00322       SQAutoFreePointers ptr;
    00323       (instance->*func)(
    00324         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00325         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00326       );
    00327       sq_pop(vm, 2);
    00328       return 0;
    00329     }
    00330
    00331     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00332     {
    00333       SQAutoFreePointers ptr;
    00334       Tcls *inst = new Tcls(
    00335         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00336         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00337       );
    00338
    00339       return inst;
    00340     }
    00341   };
    00342
    00346   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00347   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
    00348     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00349     {
    00350       SQAutoFreePointers ptr;
    00351       Tretval ret = (*func)(
    00352         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00353         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00354         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00355       );
    00356       sq_pop(vm, 3);
    00357       return Return(vm, ret);
    00358     }
    00359   };
    00360
    00364   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00365   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
    00366     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00367     {
    00368       SQAutoFreePointers ptr;
    00369       (*func)(
    00370         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00371         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00372         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00373       );
    00374       sq_pop(vm, 3);
    00375       return 0;
    00376     }
    00377   };
    00378
    00382   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00383   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
    00384     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00385     {
    00386       SQAutoFreePointers ptr;
    00387       Tretval ret = (instance->*func)(
    00388         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00389         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00390         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00391       );
    00392       sq_pop(vm, 3);
    00393       return Return(vm, ret);
    00394     }
    00395   };
    00396
    00400   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00401   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
    00402     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00403     {
    00404       SQAutoFreePointers ptr;
    00405       (instance->*func)(
    00406         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00407         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00408         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00409       );
    00410       sq_pop(vm, 3);
    00411       return 0;
    00412     }
    00413
    00414     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00415     {
    00416       SQAutoFreePointers ptr;
    00417       Tcls *inst = new Tcls(
    00418         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00419         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00420         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00421       );
    00422
    00423       return inst;
    00424     }
    00425   };
    00426
    00430   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00431   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
    00432     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00433     {
    00434       SQAutoFreePointers ptr;
    00435       Tretval ret = (*func)(
    00436         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00437         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00438         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00439         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00440       );
    00441       sq_pop(vm, 4);
    00442       return Return(vm, ret);
    00443     }
    00444   };
    00445
    00449   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00450   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), true> {
    00451     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00452     {
    00453       SQAutoFreePointers ptr;
    00454       (*func)(
    00455         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00456         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00457         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00458         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00459       );
    00460       sq_pop(vm, 4);
    00461       return 0;
    00462     }
    00463   };
    00464
    00468   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00469   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
    00470     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00471     {
    00472       SQAutoFreePointers ptr;
    00473       Tretval ret = (instance->*func)(
    00474         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00475         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00476         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00477         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00478       );
    00479       sq_pop(vm, 4);
    00480       return Return(vm, ret);
    00481     }
    00482   };
    00483
    00487   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00488   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), true> {
    00489     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00490     {
    00491       SQAutoFreePointers ptr;
    00492       (instance->*func)(
    00493         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00494         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00495         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00496         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00497       );
    00498       sq_pop(vm, 4);
    00499       return 0;
    00500     }
    00501
    00502     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00503     {
    00504       SQAutoFreePointers ptr;
    00505       Tcls *inst = new Tcls(
    00506         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00507         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00508         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00509         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00510       );
    00511
    00512       return inst;
    00513     }
    00514   };
    00515
    00519   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00520   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00521     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00522     {
    00523       SQAutoFreePointers ptr;
    00524       Tretval ret = (*func)(
    00525         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00526         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00527         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00528         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00529         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00530       );
    00531       sq_pop(vm, 5);
    00532       return Return(vm, ret);
    00533     }
    00534   };
    00535
    00539   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00540   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00541     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00542     {
    00543       SQAutoFreePointers ptr;
    00544       (*func)(
    00545         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00546         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00547         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00548         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00549         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00550       );
    00551       sq_pop(vm, 5);
    00552       return 0;
    00553     }
    00554   };
    00555
    00559   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00560   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00561     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00562     {
    00563       SQAutoFreePointers ptr;
    00564       Tretval ret = (instance->*func)(
    00565         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00566         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00567         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00568         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00569         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00570       );
    00571       sq_pop(vm, 5);
    00572       return Return(vm, ret);
    00573     }
    00574   };
    00575
    00579   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00580   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00581     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00582     {
    00583       SQAutoFreePointers ptr;
    00584       (instance->*func)(
    00585         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00586         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00587         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00588         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00589         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00590       );
    00591       sq_pop(vm, 5);
    00592       return 0;
    00593     }
    00594
    00595     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00596     {
    00597       SQAutoFreePointers ptr;
    00598       Tcls *inst = new Tcls(
    00599         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00600         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00601         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00602         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00603         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00604       );
    00605
    00606       return inst;
    00607     }
    00608   };
    00609
    00613   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00614   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00615     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00616     {
    00617       SQAutoFreePointers ptr;
    00618       Tretval ret = (*func)(
    00619         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00620         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00621         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00622         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00623         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00624         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00625         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00626         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00627         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00628         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00629       );
    00630       sq_pop(vm, 10);
    00631       return Return(vm, ret);
    00632     }
    00633   };
    00634
    00638   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00639   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00640     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00641     {
    00642       SQAutoFreePointers ptr;
    00643       (*func)(
    00644         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00645         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00646         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00647         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00648         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00649         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00650         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00651         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00652         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00653         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00654       );
    00655       sq_pop(vm, 10);
    00656       return 0;
    00657     }
    00658   };
    00659
    00663   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>
    00664   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00665     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00666     {
    00667       SQAutoFreePointers ptr;
    00668       Tretval ret = (instance->*func)(
    00669         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00670         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00671         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00672         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00673         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00674         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00675         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00676         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00677         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00678         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00679       );
    00680       sq_pop(vm, 10);
    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       sq_pop(vm, 10);
    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>
    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     sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -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       sq_pop(vm, nparam);
    00768       return e;
    00769     }
    00770   }
    00771
    00777   template <typename Tcls, typename Tmethod>
    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     sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -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       sq_pop(vm, nparam);
    00829       return e;
    00830     }
    00831   }
    00832
    00837   template <typename Tcls>
    00838   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
    00839   {
    00840     /* Remove the real instance too */
    00841     if (p != NULL) ((Tcls *)p)->Release();
    00842     return 0;
    00843   }
    00844
    00850   template <typename Tcls, typename Tmethod, int Tnparam>
    00851   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
    00852   {
    00853     /* Find the amount of params we got */
    00854     int nparam = sq_gettop(vm);
    00855
    00856     try {
    00857       /* Create the real instance */
    00858       Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
    00859       sq_setinstanceup(vm, -Tnparam, instance);
    00860       sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
    00861       instance->AddRef();
    00862       return 0;
    00863     } catch (SQInteger e) {
    00864       sq_pop(vm, nparam);
    00865       return e;
    00866     }
    00867   }
    00868
    00869 }; // namespace SQConvert
    00870
    00871 #endif /* SQUIRREL_HELPER_HPP */