truelight@9387: /* $Id$ */ truelight@9387: truelight@9424: /** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */ truelight@9387: truelight@9424: #ifndef SQUIRREL_HELPER_HPP truelight@9424: #define SQUIRREL_HELPER_HPP truelight@9424: truelight@9424: #include truelight@9387: truelight@9387: /** truelight@9510: * The Squirrel convert routines truelight@9387: */ truelight@9510: namespace SQConvert { truelight@9510: truelight@9510: template struct YesT { truelight@9510: static const bool Yes = Y; truelight@9510: static const bool No = !Y; truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * Helper class to recognize if the given type is void. Usage: 'IsVoidT::Yes' truelight@9510: */ truelight@9510: template struct IsVoidT : YesT {}; truelight@9510: template <> struct IsVoidT : YesT {}; truelight@9510: truelight@9510: /** truelight@9510: * Helper class to recognize if the function/method return type is void. truelight@9510: */ truelight@9510: template struct HasVoidReturnT; truelight@9510: /* functions */ truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: /* methods */ truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: template struct HasVoidReturnT : IsVoidT {}; truelight@9510: truelight@9510: truelight@9387: /** truelight@9387: * Special class to make it possible for the compiler to pick the correct GetParam(). truelight@9387: */ truelight@9387: template class ForceType { }; truelight@9387: truelight@9387: /** truelight@9387: * To return a value to squirrel, we call this function. It converts to the right format. truelight@9387: */ truelight@9387: template static int Return(HSQUIRRELVM vm, T t); truelight@9387: truelight@9510: template <> inline int Return (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; } truelight@9510: template <> inline int Return(HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; } truelight@9510: template <> inline int Return(HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; } truelight@9510: template <> inline int Return (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; } truelight@9510: template <> inline int Return (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; } truelight@9510: template <> inline int Return (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; } truelight@9510: template <> inline int Return (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; } truelight@9510: template <> inline int Return(HSQUIRRELVM vm, char *res) { if (res == NULL) sq_pushnull(vm); else sq_pushstring (vm, OTTD2FS(res), strlen(res)); free(res); return 1; } truelight@9510: truelight@9387: /** truelight@9387: * To get a param from squirrel, we call this function. It converts to the right format. truelight@9387: */ truelight@9387: template static T GetParam(ForceType, HSQUIRRELVM vm, int index); truelight@9387: truelight@9510: template <> inline uint8 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline uint16 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline uint32 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline int8 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline int16 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline int32 GetParam(ForceType , HSQUIRRELVM vm, int index) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return tmp; } truelight@9510: template <> inline bool GetParam(ForceType , HSQUIRRELVM vm, int index) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; } truelight@9510: template <> inline const char *GetParam(ForceType, HSQUIRRELVM vm, int index) { const SQChar *tmp; sq_getstring (vm, index, &tmp); return FS2OTTD(tmp); } truelight@9387: truelight@9387: /** truelight@9510: * Helper class to recognize the function type (retval type, args) and use the proper specialization truelight@9510: * for SQ callback. The partial specializations for the second arg (Tis_void_retval) are not possible truelight@9510: * on the function. Therefore the class is used instead. truelight@9510: */ truelight@9510: template ::Yes> struct HelperT; truelight@9490: truelight@9490: /** truelight@9510: * The real C++ caller for function with return value and 0 params. truelight@9437: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (*func)()); truelight@9510: } truelight@9510: }; truelight@9437: truelight@9437: /** truelight@9490: * The real C++ caller for function with no return value and 0 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (*func)(); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9510: * The real C++ caller for method with return value and 0 params. truelight@9387: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (instance->*func)()); truelight@9510: } truelight@9510: }; truelight@9387: truelight@9387: /** truelight@9510: * The real C++ caller for method with no return value and 0 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (instance->*func)(); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for function with return value and 1 param. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (*func)( truelight@9510: GetParam(ForceType(), vm, 2) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for function with no return value and 1 param. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (*func)( truelight@9510: GetParam(ForceType(), vm, 2) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for method with return value and 1 param. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9490: * The real C++ caller for method with no return value and 1 param. truelight@9437: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9510: * The real C++ caller for function with return value and 2 params. truelight@9387: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9387: truelight@9387: /** truelight@9510: * The real C++ caller for function with no return value and 2 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for method with return value and 2 params. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9490: * The real C++ caller for method with no return value and 2 params. truelight@9437: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9510: * The real C++ caller for function with return value and 3 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9437: truelight@9437: /** truelight@9490: * The real C++ caller for function with no return value and 3 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9510: * The real C++ caller for method with return value and 3 params. truelight@9480: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9480: truelight@9480: /** truelight@9510: * The real C++ caller for method with no return value and 3 params. truelight@9490: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for function with return value and 4 params. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4), truelight@9510: GetParam(ForceType(), vm, 5) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for function with no return value and 4 params. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4), truelight@9510: GetParam(ForceType(), vm, 5) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9510: truelight@9510: /** truelight@9510: * The real C++ caller for method with return value and 4 params. truelight@9510: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm) truelight@9510: { truelight@9510: return Return(vm, (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4), truelight@9510: GetParam(ForceType(), vm, 5) truelight@9510: )); truelight@9510: } truelight@9510: }; truelight@9490: truelight@9490: /** truelight@9490: * The real C++ caller for method with no return value and 4 params. truelight@9480: */ truelight@9510: template truelight@9510: struct HelperT { truelight@9510: static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm) truelight@9510: { truelight@9510: (instance->*func)( truelight@9510: GetParam(ForceType(), vm, 2), truelight@9510: GetParam(ForceType(), vm, 3), truelight@9510: GetParam(ForceType(), vm, 4), truelight@9510: GetParam(ForceType(), vm, 5) truelight@9510: ); truelight@9510: return 0; truelight@9510: } truelight@9510: }; truelight@9480: truelight@9490: truelight@9490: /** truelight@9387: * A general template for all callback functions from Squirrel. truelight@9387: * In here the function_proc is recovered, and the SQCall is called that truelight@9387: * can handle this exact amount of params. truelight@9387: */ truelight@9510: template truelight@9510: inline SQInteger DefSQCallback(HSQUIRRELVM vm) truelight@9387: { truelight@9387: /* Find the amount of params we got */ truelight@9387: int nparam = sq_gettop(vm); truelight@9387: SQUserPointer ptr = NULL; truelight@9387: SQUserPointer instance = NULL; truelight@9387: truelight@9387: /* Get the 'real' instance of this class */ truelight@9387: sq_getinstanceup(vm, 1, &instance, 0); truelight@9387: /* Get the real function pointer */ truelight@9387: sq_getuserdata(vm, nparam, &ptr, 0); truelight@9510: /* Delegate it to a template that can handle this specific function */ truelight@9510: return HelperT::SQCall((Tcls *)instance, *(Tmethod *)ptr, vm); truelight@9387: } truelight@9510: truelight@9510: }; // namespace SQConvert truelight@9387: truelight@9424: #endif /* SQUIRREL_HELPER_HPP */