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

Generated on Sun Nov 15 15:40:14 2009 for OpenTTD by  doxygen 1.5.6