/* $Id$ */
/** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */
#ifndef SQUIRREL_HELPER_HPP
#define SQUIRREL_HELPER_HPP
#include <squirrel.h>
/**
* The Squirrel convert class. It doesn't have an instance, the methods only are used.
*/
class SQConvert {
public:
/**
* Special class to make it possible for the compiler to pick the correct GetParam().
*/
template <typename T> class ForceType { };
/**
* To return a value to squirrel, we call this function. It converts to the right format.
*/
template <typename T> static int Return(HSQUIRRELVM vm, T t);
/**
* To get a param from squirrel, we call this function. It converts to the right format.
*/
template <typename T> static T GetParam(ForceType<T>, HSQUIRRELVM vm, int index);
/**
* The real C++ caller for function with a return value and 0 params.
*/
template <typename CL, typename RT>
static int SQCall(CL *instance, RT (CL::*func)(), HSQUIRRELVM vm)
{
return Return(vm, (instance->*func)());
}
/**
* The real C++ caller for function with no return value and 0 params.
*/
template <typename CL>
static int SQCall(CL *instance, void (CL::*func)(), HSQUIRRELVM vm)
{
(instance->*func)();
return 0;
}
/**
* The real C++ caller for function with a return value and 1 param.
*/
template <typename CL, typename RT, typename P1>
static int SQCall(CL *instance, RT (CL::*func)(P1), HSQUIRRELVM vm)
{
return Return(vm, (instance->*func)(
GetParam(ForceType<P1>(), vm, 2)
));
}
/**
* The real C++ caller for function with no return value and 1 param.
*/
template <typename CL, typename P1>
static int SQCall(CL *instance, void (CL::*func)(P1), HSQUIRRELVM vm)
{
(instance->*func)(
GetParam(ForceType<P1>(), vm, 2)
);
return 0;
}
/**
* The real C++ caller for function with a return value and 2 params.
*/
template <typename CL, typename RT, typename P1, typename P2>
static int SQCall(CL *instance, RT (CL::*func)(P1, P2), HSQUIRRELVM vm)
{
return Return(vm, (instance->*func)(
GetParam(ForceType<P1>(), vm, 2),
GetParam(ForceType<P2>(), vm, 3)
));
}
/**
* The real C++ caller for function with no return value and 2 params.
*/
template <typename CL, typename P1, typename P2>
static int SQCall(CL *instance, void (CL::*func)(P1, P2), HSQUIRRELVM vm)
{
(instance->*func)(
GetParam(ForceType<P1>(), vm, 2),
GetParam(ForceType<P2>(), vm, 3)
);
return 0;
}
/**
* The real C++ caller for function with a return value and 3 params.
*/
template <typename CL, typename RT, typename P1, typename P2, typename P3>
static int SQCall(CL *instance, RT (CL::*func)(P1, P2, P3), HSQUIRRELVM vm)
{
return Return(vm, (instance->*func)(
GetParam(ForceType<P1>(), vm, 2),
GetParam(ForceType<P2>(), vm, 3),
GetParam(ForceType<P3>(), vm, 4)
));
}
/**
* The real C++ caller for function with no return value and 3 params.
*/
template <typename CL, typename P1, typename P2, typename P3>
static int SQCall(CL *instance, void (CL::*func)(P1, P2, P3), HSQUIRRELVM vm)
{
(instance->*func)(
GetParam(ForceType<P1>(), vm, 2),
GetParam(ForceType<P2>(), vm, 3),
GetParam(ForceType<P3>(), vm, 4)
);
return 0;
}
/**
* A general template for all callback functions from Squirrel.
* In here the function_proc is recovered, and the SQCall is called that
* can handle this exact amount of params.
*/
template <typename CL, typename Func>
static SQInteger DefSQCallback(HSQUIRRELVM vm)
{
/* Find the amount of params we got */
int nparam = sq_gettop(vm);
SQUserPointer ptr = NULL;
SQUserPointer instance = NULL;
/* Get the 'real' instance of this class */
sq_getinstanceup(vm, 1, &instance, 0);
/* Get the real function pointer */
sq_getuserdata(vm, nparam, &ptr, 0);
/* Deligate it to a template that can handle this specific function */
return SQCall((CL *)instance, *(Func *)ptr, vm);
}
};
#endif /* SQUIRREL_HELPER_HPP */