Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 7, 2017, 7:26:12 PM (6 years ago)
Author:
kohlia
Message:

Lua bindings should work now

Location:
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp

    r11549 r11552  
    4545            return LUA_ERRSYNTAX;
    4646        }
    47         orxonox::orxout(orxonox::user_warning) << "what" << std::endl;
    4847
    4948        // Call getArgument for every argument seperately to convert each argument
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc

    r11549 r11552  
    44#include <string>
    55
     6// Holds a list of all current callback references
     7std::list<std::unique_ptr<int> > LuaTBTypedStack::callbackRefs = {};
     8
    69// Explicit and full specializations need to be in a .cpp file
    710
    811template<>
    9 int LuaTBTypedStack::popFromLuaStack<int>(lua_State *lua)
     12int LuaTBTypedStack::getFromLuaStack<int>(lua_State *lua)
    1013{ return lua_tointeger(lua, lua_gettop(lua)); }
    1114
    1215template<>
    13 double LuaTBTypedStack::popFromLuaStack<double>(lua_State *lua)
     16double LuaTBTypedStack::getFromLuaStack<double>(lua_State *lua)
    1417{ return lua_tonumber(lua, lua_gettop(lua)); }
    1518
    1619template<>
    17 std::string LuaTBTypedStack::popFromLuaStack<std::string>(lua_State *lua)
     20std::string LuaTBTypedStack::getFromLuaStack<std::string>(lua_State *lua)
    1821{ return lua_tostring(lua, lua_gettop(lua)); }
    1922
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h

    r11549 r11552  
    1414{
    1515public:
    16     // Get an argument from the lua stack and convert it to type 'T'
     16
     17    // Get a non-function argument from the lua stack and convert it to type 'T'
     18    // Pops the value from the stack.
    1719    template<typename T>
    18     static T getArgument(lua_State *lua)
     20    static typename std::enable_if<!IsCallable<T>::value, T>::type getArgument(lua_State *lua)
    1921    {
    20         T value = LuaTBTypedStack::popFromLuaStack<T>(lua);
     22        T value = LuaTBTypedStack::getFromLuaStack<T>(lua);
    2123        lua_pop(lua, 1);
    2224        return value;
    2325    }
    24 
    25 private:
    26     // Gets the top element of the lua stack and converts it to the appropriate
    27     // type. Only works for certain types, if 'T' is none of these types, you'll
    28     // get an error.
    29     template<typename T>
    30     static typename std::enable_if<!IsCallable<T>::value, T>::type popFromLuaStack(lua_State *lua);
    3126
    3227    // Specialization if 'T' is a callable type (std::function). Saves the lua
     
    3530    // object.
    3631    template<typename T>
    37     static typename std::enable_if<IsCallable<T>::value, T>::type popFromLuaStack(lua_State *lua)
     32    static typename std::enable_if<IsCallable<T>::value, T>::type getArgument(lua_State *lua)
    3833    {
    39         return GetLuaCallback<decltype(&T::operator())>::value(lua, luaL_ref(lua, LUA_REGISTRYINDEX));
     34        // Here's the tricky part. Apparently, references in the registry can only
     35        // be called once. This is why we always have to re-add it to the registry
     36        // after every call. That means, we need a persistent variable for 'ref' and
     37        // that's only possible with a pointer in this case.
     38        int *ref = new int(luaL_ref(lua, LUA_REGISTRYINDEX));
     39        LuaTBTypedStack::callbackRefs.push_back(std::unique_ptr<int>(ref));
     40
     41        return GetLuaCallback<decltype(&T::operator())>::value(lua, ref);
    4042    }
    4143
    42     // Get a function that will call a lua callback
     44private:
    4345    template<typename T> struct GetLuaCallback;
     46
     47    // Gets a value from the top of the lua stack and returns it with the proper type.
     48    // Does not pop the value!
     49    template<typename T> static T getFromLuaStack(lua_State *lua);
    4450
    4551    // This class is only valid for std::function types. The type argument will not
     
    4753    // std::function<>::operator(), which is also the reason for the 'const'.
    4854    template<typename Ret, typename... Args>
    49     struct GetLuaCallback<Ret(std::function<Ret(Args...)>::*)(Args...) const>
     55    struct GetLuaCallback<void (std::function<Ret(Args...)>::*)(Args...) const>
    5056    {
    5157        // Returns a lambda that will push the arguments to the lua stack and call
     
    5359        // because we need the additional arguments 'lua' and 'ref' which we would
    5460        // like to hide from the user.
    55         static std::function<Ret (Args...)> value(lua_State *lua, int ref)
     61        static std::function<void (Args...)> value(lua_State *lua, int *ref)
    5662        {
    57             orxonox::orxout(orxonox::user_warning) << "Ref1: " << ref << std::endl;
    58             return [lua, ref](Args... args){return callLuaFunction<Ret, Args...>(lua, ref, args...);};
     63            return [lua, ref](Args... args){callLuaFunction<Ret, Args...>(lua, ref, args...);};
    5964        }
    6065    };
     
    6267    // Pushes all arguments to the lua stack and calls a lua function afterwards
    6368    template<typename Ret, typename... Args>
    64     static Ret callLuaFunction(lua_State *lua, int ref, Args... args)
     69    static void callLuaFunction(lua_State *lua, int *ref, Args... args)
    6570    {
    66         lua_rawgeti(lua, LUA_REGISTRYINDEX, ref);
     71        // Get the value of the callback from the registry and push it to the stack
     72        lua_rawgeti(lua, LUA_REGISTRYINDEX, *ref);
     73
     74        // Duplicate it on the stack so we can save it in the registry again after
     75        // we called the callback.
     76        lua_pushvalue(lua, 1);
     77
    6778        // We pass one extra argument in case the function has no arguments at all
    6879        pushArgumentsToLuaStack<Args...>(lua, args..., false);
    69         int r = lua_pcall(lua, 1, sizeof...(args), 0);
     80        lua_pcall(lua, sizeof...(args), 0, 0);
    7081
    71         orxonox::orxout(orxonox::user_warning) << "Ref2: " << ref << std::endl;
    72 if(r != 0){
    73         const char* message = lua_tostring(lua, -1);
    74         std::cout << message << std::endl;
    75         lua_pop(lua, 1);
    76 }
     82        // Release the old reference and save the function in the registry again
     83        lua_unref(lua, *ref);
     84        *ref = luaL_ref(lua, LUA_REGISTRYINDEX);
     85    }
    7786
    78         // TODO
    79         return Ret();
    80     }
    8187    // This is needed in case the function has no arguments at all. Otherwise, we
    8288    // would have a missing argument for such function. This is also why we pass
     
    97103    template<typename T>
    98104    static void pushToLuaStack(lua_State *lua, T value);
     105
     106    static std::list<std::unique_ptr<int> > callbackRefs;
    99107};
    100108
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc

    r11549 r11552  
    8282{
    8383    this->timeouts.push_back(std::make_pair(callback, static_cast<float>(timeout)));
    84     orxout(user_warning) << "Calling should work..." << std::endl;
    85     callback();
    8684}
    8785
     
    9593        if(timeout->second <= 0)
    9694        {
    97             orxout(user_warning) << "Calling..." << std::endl;
    9895            timeout->first();
    9996            timeout = this->timeouts.erase(timeout);
  • code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc

    r11549 r11552  
    11
    22#include "scriptable_controller_api.h"
    3 #include <chrono>
    4 #include "lua.hpp"
    53#include "luatb.h"
    64#include "scriptable_controller.h"
     
    3028void ScriptableControllerAPI::registerAfterTimeout(std::function<void (void)> callback, double timeout)
    3129{
     30    // TODO Extend timer class to accept std::function
    3231    this->controller_->registerTimeout(callback, timeout);
    3332}
     
    3534int ScriptableControllerAPI::registerAtNearObject(std::function<void (int, int)> callback, int obj1, int obj2, double distance)
    3635{
    37     orxout(user_warning) << "Working!" << std::endl;
     36
    3837}
    3938
Note: See TracChangeset for help on using the changeset viewer.