# squirrel_helper.hpp

Go to the documentation of this file.

    00001 /* $Id: squirrel_helper.hpp 17235 2009-08-20 12:22:31Z rubidium $ */
    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 { sq_pushstring(vm, OTTD2FS(res), -1); free(res); } return 1; }
    00084   template <> inline int Return<const char *>(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, OTTD2FS(res), -1); } 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 void       *GetParam(ForceType<void *>      , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
    00100   template <> inline const char *GetParam(ForceType<const char *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
    00101   {
    00102     sq_tostring(vm, index);
    00103     const SQChar *tmp;
    00104     sq_getstring(vm, -1, &tmp);
    00105     char *tmp_str = strdup(FS2OTTD(tmp));
    00106     sq_poptop(vm);
    00107     *ptr->Append() = (void *)tmp_str;
    00108     str_validate(tmp_str, tmp_str + strlen(tmp_str));
    00109     return tmp_str;
    00110   }
    00111
    00112   template <> inline Array      *GetParam(ForceType<Array *>,      HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
    00113   {
    00114     SQObject obj;
    00115     sq_getstackobj(vm, index, &obj);
    00116     sq_pushobject(vm, obj);
    00117     sq_pushnull(vm);
    00118
    00119     SmallVector<int32, 2> data;
    00120
    00121     while (SQ_SUCCEEDED(sq_next(vm, -2))) {
    00122       SQInteger tmp;
    00123       if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
    00124         *data.Append() = (int32)tmp;
    00125       } else {
    00126         sq_pop(vm, 4);
    00127         throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric"));
    00128       }
    00129
    00130       sq_pop(vm, 2);
    00131     }
    00132     sq_pop(vm, 2);
    00133
    00134     Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length());
    00135     arr->size = data.Length();
    00136     memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length());
    00137
    00138     *ptr->Append() = arr;
    00139     return arr;
    00140   }
    00141
    00147   template <typename Tfunc, bool Tis_void_retval = HasVoidReturnT<Tfunc>::Yes> struct HelperT;
    00148
    00152   template <typename Tretval>
    00153   struct HelperT<Tretval (*)(), false> {
    00154     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00155     {
    00156       return Return(vm, (*func)());
    00157     }
    00158   };
    00159
    00163   template <typename Tretval>
    00164   struct HelperT<Tretval (*)(), true> {
    00165     static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
    00166     {
    00167       (*func)();
    00168       return 0;
    00169     }
    00170   };
    00171
    00175   template <class Tcls, typename Tretval>
    00176   struct HelperT<Tretval (Tcls::*)(), false> {
    00177     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00178     {
    00179       return Return(vm, (instance->*func)());
    00180     }
    00181   };
    00182
    00186   template <class Tcls, typename Tretval>
    00187   struct HelperT<Tretval (Tcls::*)(), true> {
    00188     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00189     {
    00190       (instance->*func)();
    00191       return 0;
    00192     }
    00193
    00194     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
    00195     {
    00196       return new Tcls();
    00197     }
    00198   };
    00199
    00203   template <typename Tretval, typename Targ1>
    00204   struct HelperT<Tretval (*)(Targ1), false> {
    00205     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00206     {
    00207       SQAutoFreePointers ptr;
    00208       Tretval ret = (*func)(
    00209         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00210       );
    00211       sq_pop(vm, 1);
    00212       return Return(vm, ret);
    00213     }
    00214   };
    00215
    00219   template <typename Tretval, typename Targ1>
    00220   struct HelperT<Tretval (*)(Targ1), true> {
    00221     static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
    00222     {
    00223       SQAutoFreePointers ptr;
    00224       (*func)(
    00225         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00226       );
    00227       sq_pop(vm, 1);
    00228       return 0;
    00229     }
    00230   };
    00231
    00235   template <class Tcls, typename Tretval, typename Targ1>
    00236   struct HelperT<Tretval (Tcls::*)(Targ1), false> {
    00237     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00238     {
    00239       SQAutoFreePointers ptr;
    00240       Tretval ret = (instance->*func)(
    00241         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00242       );
    00243       sq_pop(vm, 1);
    00244       return Return(vm, ret);
    00245     }
    00246   };
    00247
    00251   template <class Tcls, typename Tretval, typename Targ1>
    00252   struct HelperT<Tretval (Tcls::*)(Targ1), true> {
    00253     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00254     {
    00255       SQAutoFreePointers ptr;
    00256       (instance->*func)(
    00257         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00258       );
    00259       sq_pop(vm, 1);
    00260       return 0;
    00261     }
    00262
    00263     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
    00264     {
    00265       SQAutoFreePointers ptr;
    00266       Tcls *inst = new Tcls(
    00267         GetParam(ForceType<Targ1>(), vm, 2, &ptr)
    00268       );
    00269
    00270       return inst;
    00271     }
    00272   };
    00273
    00277   template <typename Tretval, typename Targ1, typename Targ2>
    00278   struct HelperT<Tretval (*)(Targ1, Targ2), false> {
    00279     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00280     {
    00281       SQAutoFreePointers ptr;
    00282       Tretval ret = (*func)(
    00283         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00284         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00285       );
    00286       sq_pop(vm, 2);
    00287       return Return(vm, ret);
    00288     }
    00289   };
    00290
    00294   template <typename Tretval, typename Targ1, typename Targ2>
    00295   struct HelperT<Tretval (*)(Targ1, Targ2), true> {
    00296     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00297     {
    00298       SQAutoFreePointers ptr;
    00299       (*func)(
    00300         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00301         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00302       );
    00303       sq_pop(vm, 2);
    00304       return 0;
    00305     }
    00306   };
    00307
    00311   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00312   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), false> {
    00313     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00314     {
    00315       SQAutoFreePointers ptr;
    00316       Tretval ret = (instance->*func)(
    00317         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00318         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00319       );
    00320       sq_pop(vm, 2);
    00321       return Return(vm, ret);
    00322     }
    00323   };
    00324
    00328   template <class Tcls, typename Tretval, typename Targ1, typename Targ2>
    00329   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2), true> {
    00330     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00331     {
    00332       SQAutoFreePointers ptr;
    00333       (instance->*func)(
    00334         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00335         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00336       );
    00337       sq_pop(vm, 2);
    00338       return 0;
    00339     }
    00340
    00341     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
    00342     {
    00343       SQAutoFreePointers ptr;
    00344       Tcls *inst = new Tcls(
    00345         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00346         GetParam(ForceType<Targ2>(), vm, 3, &ptr)
    00347       );
    00348
    00349       return inst;
    00350     }
    00351   };
    00352
    00356   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00357   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), false> {
    00358     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00359     {
    00360       SQAutoFreePointers ptr;
    00361       Tretval ret = (*func)(
    00362         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00363         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00364         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00365       );
    00366       sq_pop(vm, 3);
    00367       return Return(vm, ret);
    00368     }
    00369   };
    00370
    00374   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00375   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3), true> {
    00376     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00377     {
    00378       SQAutoFreePointers ptr;
    00379       (*func)(
    00380         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00381         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00382         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00383       );
    00384       sq_pop(vm, 3);
    00385       return 0;
    00386     }
    00387   };
    00388
    00392   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00393   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), false> {
    00394     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00395     {
    00396       SQAutoFreePointers ptr;
    00397       Tretval ret = (instance->*func)(
    00398         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00399         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00400         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00401       );
    00402       sq_pop(vm, 3);
    00403       return Return(vm, ret);
    00404     }
    00405   };
    00406
    00410   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3>
    00411   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3), true> {
    00412     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00413     {
    00414       SQAutoFreePointers ptr;
    00415       (instance->*func)(
    00416         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00417         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00418         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00419       );
    00420       sq_pop(vm, 3);
    00421       return 0;
    00422     }
    00423
    00424     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
    00425     {
    00426       SQAutoFreePointers ptr;
    00427       Tcls *inst = new Tcls(
    00428         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00429         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00430         GetParam(ForceType<Targ3>(), vm, 4, &ptr)
    00431       );
    00432
    00433       return inst;
    00434     }
    00435   };
    00436
    00440   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00441   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4), false> {
    00442     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00443     {
    00444       SQAutoFreePointers ptr;
    00445       Tretval ret = (*func)(
    00446         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00447         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00448         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00449         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00450       );
    00451       sq_pop(vm, 4);
    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       sq_pop(vm, 4);
    00471       return 0;
    00472     }
    00473   };
    00474
    00478   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4>
    00479   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4), false> {
    00480     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00481     {
    00482       SQAutoFreePointers ptr;
    00483       Tretval ret = (instance->*func)(
    00484         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00485         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00486         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00487         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00488       );
    00489       sq_pop(vm, 4);
    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       sq_pop(vm, 4);
    00509       return 0;
    00510     }
    00511
    00512     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
    00513     {
    00514       SQAutoFreePointers ptr;
    00515       Tcls *inst = new Tcls(
    00516         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00517         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00518         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00519         GetParam(ForceType<Targ4>(), vm, 5, &ptr)
    00520       );
    00521
    00522       return inst;
    00523     }
    00524   };
    00525
    00529   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00530   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00531     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00532     {
    00533       SQAutoFreePointers ptr;
    00534       Tretval ret = (*func)(
    00535         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00536         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00537         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00538         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00539         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00540       );
    00541       sq_pop(vm, 5);
    00542       return Return(vm, ret);
    00543     }
    00544   };
    00545
    00549   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00550   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00551     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00552     {
    00553       SQAutoFreePointers ptr;
    00554       (*func)(
    00555         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00556         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00557         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00558         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00559         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00560       );
    00561       sq_pop(vm, 5);
    00562       return 0;
    00563     }
    00564   };
    00565
    00569   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00570   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), false> {
    00571     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00572     {
    00573       SQAutoFreePointers ptr;
    00574       Tretval ret = (instance->*func)(
    00575         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00576         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00577         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00578         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00579         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00580       );
    00581       sq_pop(vm, 5);
    00582       return Return(vm, ret);
    00583     }
    00584   };
    00585
    00589   template <class Tcls, typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5>
    00590   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5), true> {
    00591     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00592     {
    00593       SQAutoFreePointers ptr;
    00594       (instance->*func)(
    00595         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00596         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00597         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00598         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00599         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00600       );
    00601       sq_pop(vm, 5);
    00602       return 0;
    00603     }
    00604
    00605     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
    00606     {
    00607       SQAutoFreePointers ptr;
    00608       Tcls *inst = new Tcls(
    00609         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00610         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00611         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00612         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00613         GetParam(ForceType<Targ5>(), vm, 6, &ptr)
    00614       );
    00615
    00616       return inst;
    00617     }
    00618   };
    00619
    00623   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00624   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00625     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00626     {
    00627       SQAutoFreePointers ptr;
    00628       Tretval ret = (*func)(
    00629         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00630         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00631         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00632         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00633         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00634         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00635         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00636         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00637         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00638         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00639       );
    00640       sq_pop(vm, 10);
    00641       return Return(vm, ret);
    00642     }
    00643   };
    00644
    00648   template <typename Tretval, typename Targ1, typename Targ2, typename Targ3, typename Targ4, typename Targ5, typename Targ6, typename Targ7, typename Targ8, typename Targ9, typename Targ10>
    00649   struct HelperT<Tretval (*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00650     static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00651     {
    00652       SQAutoFreePointers ptr;
    00653       (*func)(
    00654         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00655         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00656         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00657         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00658         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00659         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00660         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00661         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00662         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00663         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00664       );
    00665       sq_pop(vm, 10);
    00666       return 0;
    00667     }
    00668   };
    00669
    00673   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>
    00674   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), false> {
    00675     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00676     {
    00677       SQAutoFreePointers ptr;
    00678       Tretval ret = (instance->*func)(
    00679         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00680         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00681         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00682         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00683         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00684         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00685         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00686         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00687         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00688         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00689       );
    00690       sq_pop(vm, 10);
    00691       return Return(vm, ret);
    00692     }
    00693   };
    00694
    00698   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>
    00699   struct HelperT<Tretval (Tcls::*)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), true> {
    00700     static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00701     {
    00702       SQAutoFreePointers ptr;
    00703       (instance->*func)(
    00704         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00705         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00706         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00707         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00708         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00709         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00710         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00711         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00712         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00713         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00714       );
    00715       sq_pop(vm, 10);
    00716       return 0;
    00717     }
    00718
    00719     static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
    00720     {
    00721       SQAutoFreePointers ptr;
    00722       Tcls *inst = new Tcls(
    00723         GetParam(ForceType<Targ1>(), vm, 2, &ptr),
    00724         GetParam(ForceType<Targ2>(), vm, 3, &ptr),
    00725         GetParam(ForceType<Targ3>(), vm, 4, &ptr),
    00726         GetParam(ForceType<Targ4>(), vm, 5, &ptr),
    00727         GetParam(ForceType<Targ5>(), vm, 6, &ptr),
    00728         GetParam(ForceType<Targ6>(), vm, 7, &ptr),
    00729         GetParam(ForceType<Targ7>(), vm, 8, &ptr),
    00730         GetParam(ForceType<Targ8>(), vm, 9, &ptr),
    00731         GetParam(ForceType<Targ9>(), vm, 10, &ptr),
    00732         GetParam(ForceType<Targ10>(), vm, 11, &ptr)
    00733       );
    00734
    00735       return inst;
    00736     }
    00737   };
    00738
    00739
    00745   template <typename Tcls, typename Tmethod>
    00746   inline SQInteger DefSQNonStaticCallback(HSQUIRRELVM vm)
    00747   {
    00748     /* Find the amount of params we got */
    00749     int nparam = sq_gettop(vm);
    00750     SQUserPointer ptr = NULL;
    00751     SQUserPointer real_instance = NULL;
    00752     HSQOBJECT instance;
    00753
    00754     /* Get the 'SQ' instance of this class */
    00755     Squirrel::GetInstance(vm, &instance);
    00756
    00757     /* Protect against calls to a non-static method in a static way */
    00758     sq_pushroottable(vm);
    00759     sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -1);
    00760     sq_get(vm, -2);
    00761     sq_pushobject(vm, instance);
    00762     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00763     sq_pop(vm, 3);
    00764
    00765     /* Get the 'real' instance of this class */
    00766     sq_getinstanceup(vm, 1, &real_instance, 0);
    00767     /* Get the real function pointer */
    00768     sq_getuserdata(vm, nparam, &ptr, 0);
    00769     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00770     /* Remove the userdata from the stack */
    00771     sq_pop(vm, 1);
    00772
    00773     try {
    00774       /* Delegate it to a template that can handle this specific function */
    00775       return HelperT<Tmethod>::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm);
    00776     } catch (SQInteger e) {
    00777       sq_pop(vm, nparam);
    00778       return e;
    00779     }
    00780   }
    00781
    00787   template <typename Tcls, typename Tmethod>
    00788   inline SQInteger DefSQAdvancedNonStaticCallback(HSQUIRRELVM vm)
    00789   {
    00790     /* Find the amount of params we got */
    00791     int nparam = sq_gettop(vm);
    00792     SQUserPointer ptr = NULL;
    00793     SQUserPointer real_instance = NULL;
    00794     HSQOBJECT instance;
    00795
    00796     /* Get the 'SQ' instance of this class */
    00797     Squirrel::GetInstance(vm, &instance);
    00798
    00799     /* Protect against calls to a non-static method in a static way */
    00800     sq_pushroottable(vm);
    00801     sq_pushstring(vm, OTTD2FS(Tcls::GetClassName()), -1);
    00802     sq_get(vm, -2);
    00803     sq_pushobject(vm, instance);
    00804     if (sq_instanceof(vm) != SQTrue) return sq_throwerror(vm, _SC("class method is non-static"));
    00805     sq_pop(vm, 3);
    00806
    00807     /* Get the 'real' instance of this class */
    00808     sq_getinstanceup(vm, 1, &real_instance, 0);
    00809     /* Get the real function pointer */
    00810     sq_getuserdata(vm, nparam, &ptr, 0);
    00811     if (real_instance == NULL) return sq_throwerror(vm, _SC("couldn't detect real instance of class for non-static call"));
    00812     /* Remove the userdata from the stack */
    00813     sq_pop(vm, 1);
    00814
    00815     /* Call the function, which its only param is always the VM */
    00816     return (SQInteger)(((Tcls *)real_instance)->*(*(Tmethod *)ptr))(vm);
    00817   }
    00818
    00824   template <typename Tcls, typename Tmethod>
    00825   inline SQInteger DefSQStaticCallback(HSQUIRRELVM vm)
    00826   {
    00827     /* Find the amount of params we got */
    00828     int nparam = sq_gettop(vm);
    00829     SQUserPointer ptr = NULL;
    00830
    00831     /* Get the real function pointer */
    00832     sq_getuserdata(vm, nparam, &ptr, 0);
    00833
    00834     try {
    00835       /* Delegate it to a template that can handle this specific function */
    00836       return HelperT<Tmethod>::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm);
    00837     } catch (SQInteger e) {
    00838       sq_pop(vm, nparam);
    00839       return e;
    00840     }
    00841   }
    00842
    00847   template <typename Tcls>
    00848   static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size)
    00849   {
    00850     /* Remove the real instance too */
    00851     if (p != NULL) ((Tcls *)p)->Release();
    00852     return 0;
    00853   }
    00854
    00860   template <typename Tcls, typename Tmethod, int Tnparam>
    00861   inline SQInteger DefSQConstructorCallback(HSQUIRRELVM vm)
    00862   {
    00863     /* Find the amount of params we got */
    00864     int nparam = sq_gettop(vm);
    00865
    00866     try {
    00867       /* Create the real instance */
    00868       Tcls *instance = HelperT<Tmethod>::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm);
    00869       sq_setinstanceup(vm, -Tnparam, instance);
    00870       sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback<Tcls>);
    00871       instance->AddRef();
    00872       return 0;
    00873     } catch (SQInteger e) {
    00874       sq_pop(vm, nparam);
    00875       return e;
    00876     }
    00877   }
    00878
    00879 }; // namespace SQConvert
    00880
    00881 #endif /* SQUIRREL_HELPER_HPP */