src/squirrel_helper.hpp
author truelight
Thu, 15 Mar 2007 22:22:51 +0000
branchnoai
changeset 9426 b90c0d1a36b7
parent 9424 90e9aa6326f3
child 9434 2e71647c2c1c
permissions -rw-r--r--
(svn r9229) [NoAI] -Change: move more header-mess from .hpp to .cpp
/* $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

#ifdef _UNICODE
/* Disable unicode for squirrel to allow compilation with MINGW
 * and simplify coding for WIN32 (squirrel headers miss a lot of "string" functions)
 */
#undef _UNICODE
#endif
#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 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 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 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)
					));
	}

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