#include #include #include #include "luatb_typed_stack.h" // TODO Make free functions work // This class is only valid for function types. As a neat side-effect, having // this specialization in the .ipp file, also hides all of the private members // from the user (kind of). template class LuaTB { public: template static void registerFunction(ThisType *_this, lua_State *lua, std::string name) { // Store the 'this' pointer of the caller in the extraspace LuaTB::stateToClassMap[lua] = _this; // Make a function visible to lua that will call 'func' with the correct // arguments lua_register(lua, name.c_str(), toLuaSignature); } private: static std::map stateToClassMap; // Represents a function that can made visible to lua with the correct // signature. It will call the corresponding C++ function with the // correctly typed arguments template static int toLuaSignature(lua_State *lua) { // The index of the topmost item on the stack equals the size of // the stack, which also equals the number of arguments int argc = lua_gettop(lua); // Check if the number of arguments match if(argc != sizeof...(Args)) { std::cerr << "ERROR: LuaTB: Lua script called a function with wrong number of arguments (" << argc << " given, " << sizeof...(Args) << " expected)" << std::endl; return LUA_ERRSYNTAX; } // Call getArgument for every argument seperately to convert each argument // to the correct type and call the function afterwards ((*LuaTB::stateToClassMap[lua]).*func)( (LuaTBTypedStack::getArgument(lua))... ); return 0; } }; // This needs to be here and not in a source file, because the compiler can't know // the template types if it's in a separate module. template std::map LuaTB::stateToClassMap = std::map();