src/squirrel_helper.hpp
author truelight
Mon, 19 Mar 2007 12:30:11 +0000
branchnoai
changeset 9475 58c20c0e394f
parent 9437 28e0105114a4
child 9480 d071f885f918
permissions -rw-r--r--
(svn r9320) [NoAI] -Fix: added some doxygen comments to make doxygen happy
/* $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 */