Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp @ 12126

Last change on this file since 12126 was 11552, checked in by kohlia, 7 years ago

Lua bindings should work now

File size: 2.3 KB
RevLine 
[11519]1
2#include <lua.hpp>
3#include <iostream>
4#include <type_traits>
5#include "luatb_typed_stack.h"
6
7
8// TODO Make free functions work
9
10// This class is only valid for function types. As a neat side-effect, having
11// this specialization in the .ipp file, also hides all of the private members
12// from the user (kind of).
13template<typename ThisType, typename Ret, typename... Args>
14class LuaTB<ThisType, Ret (ThisType::*)(Args...)>
15{
16public:
17    template<Ret (ThisType::*func)(Args...)>
18    static void registerFunction(ThisType *_this, lua_State *lua, std::string name)
19    {
20        // Store the 'this' pointer of the caller in the extraspace
[11549]21        LuaTB<ThisType, Ret (ThisType::*)(Args...)>::stateToClassMap[lua] = _this;
[11519]22
23        // Make a function visible to lua that will call 'func' with the correct
24        // arguments
25        lua_register(lua, name.c_str(), toLuaSignature<func>);
26    }
27
28private:
[11549]29    static std::map<lua_State*, ThisType*> stateToClassMap;
30
[11519]31    // Represents a function that can made visible to lua with the correct
32    // signature. It will call the corresponding C++ function with the
33    // correctly typed arguments
34    template<Ret (ThisType::*func)(Args...)>
35    static int toLuaSignature(lua_State *lua)
36    {
[11549]37        // The index of the topmost item on the stack equals the size of
38        // the stack, which also equals the number of arguments
39        int argc = lua_gettop(lua);
[11519]40
41        // Check if the number of arguments match
42        if(argc != sizeof...(Args))
43        {
[11549]44            std::cerr << "ERROR: LuaTB: Lua script called a function with wrong number of arguments (" << argc << " given, " << sizeof...(Args) << " expected)" << std::endl;
[11519]45            return LUA_ERRSYNTAX;
46        }
47
48        // Call getArgument for every argument seperately to convert each argument
49        // to the correct type and call the function afterwards
[11549]50        ((*LuaTB<ThisType, Ret (ThisType::*)(Args...)>::stateToClassMap[lua]).*func)( (LuaTBTypedStack::getArgument<Args>(lua))... );
[11519]51
52        return 0;
53    }
54};
[11549]55
56// This needs to be here and not in a source file, because the compiler can't know
57// the template types if it's in a separate module.
58template<typename ThisType, typename Ret, typename... Args>
59std::map<lua_State*, ThisType*> LuaTB<ThisType, Ret (ThisType::*)(Args...)>::stateToClassMap = std::map<lua_State*, ThisType*>();
Note: See TracBrowser for help on using the repository browser.