squirrel_helper.hpp

Go to the documentation of this file.
00001 /* $Id: squirrel_helper.hpp 15629 2009-03-06 14:21:26Z yexo $ */
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), 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 {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; str_validate(tmp_str, tmp_str + strlen(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 */

Generated on Sun Mar 15 22:49:49 2009 for openttd by  doxygen 1.5.6