#include #include #include #include "scriptable_controller_api.h" #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 // *static_cast(lua_getextraspace(lua)) = _this; // Make a function visible to lua that will call 'func' with the correct // arguments lua_register(lua, name.c_str(), toLuaSignature); } private: // 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 number of arguments is the first item on the stack int argc = lua_tointeger(lua, lua_gettop(lua)); lua_pop(lua, 1); // 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" << std::endl; return LUA_ERRSYNTAX; } // Retrieve 'this' pointer of caller // ThisType *_this = *static_cast(lua_getextraspace(lua)); ThisType *_this = orxonox::ScriptableControllerAPI::this_; // Call getArgument for every argument seperately to convert each argument // to the correct type and call the function afterwards ((*_this).*func)( (LuaTBTypedStack::getArgument(lua))... ); return 0; } };