Changeset 11552 for code/branches/ScriptableController_HS17
- Timestamp:
- Nov 7, 2017, 7:26:12 PM (7 years ago)
- 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 45 45 return LUA_ERRSYNTAX; 46 46 } 47 orxonox::orxout(orxonox::user_warning) << "what" << std::endl;48 47 49 48 // Call getArgument for every argument seperately to convert each argument -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc
r11549 r11552 4 4 #include <string> 5 5 6 // Holds a list of all current callback references 7 std::list<std::unique_ptr<int> > LuaTBTypedStack::callbackRefs = {}; 8 6 9 // Explicit and full specializations need to be in a .cpp file 7 10 8 11 template<> 9 int LuaTBTypedStack:: popFromLuaStack<int>(lua_State *lua)12 int LuaTBTypedStack::getFromLuaStack<int>(lua_State *lua) 10 13 { return lua_tointeger(lua, lua_gettop(lua)); } 11 14 12 15 template<> 13 double LuaTBTypedStack:: popFromLuaStack<double>(lua_State *lua)16 double LuaTBTypedStack::getFromLuaStack<double>(lua_State *lua) 14 17 { return lua_tonumber(lua, lua_gettop(lua)); } 15 18 16 19 template<> 17 std::string LuaTBTypedStack:: popFromLuaStack<std::string>(lua_State *lua)20 std::string LuaTBTypedStack::getFromLuaStack<std::string>(lua_State *lua) 18 21 { return lua_tostring(lua, lua_gettop(lua)); } 19 22 -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h
r11549 r11552 14 14 { 15 15 public: 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. 17 19 template<typename T> 18 static TgetArgument(lua_State *lua)20 static typename std::enable_if<!IsCallable<T>::value, T>::type getArgument(lua_State *lua) 19 21 { 20 T value = LuaTBTypedStack:: popFromLuaStack<T>(lua);22 T value = LuaTBTypedStack::getFromLuaStack<T>(lua); 21 23 lua_pop(lua, 1); 22 24 return value; 23 25 } 24 25 private:26 // Gets the top element of the lua stack and converts it to the appropriate27 // type. Only works for certain types, if 'T' is none of these types, you'll28 // get an error.29 template<typename T>30 static typename std::enable_if<!IsCallable<T>::value, T>::type popFromLuaStack(lua_State *lua);31 26 32 27 // Specialization if 'T' is a callable type (std::function). Saves the lua … … 35 30 // object. 36 31 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) 38 33 { 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); 40 42 } 41 43 42 // Get a function that will call a lua callback 44 private: 43 45 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); 44 50 45 51 // This class is only valid for std::function types. The type argument will not … … 47 53 // std::function<>::operator(), which is also the reason for the 'const'. 48 54 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> 50 56 { 51 57 // Returns a lambda that will push the arguments to the lua stack and call … … 53 59 // because we need the additional arguments 'lua' and 'ref' which we would 54 60 // like to hide from the user. 55 static std::function< Ret (Args...)> value(lua_State *lua, intref)61 static std::function<void (Args...)> value(lua_State *lua, int *ref) 56 62 { 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...);}; 59 64 } 60 65 }; … … 62 67 // Pushes all arguments to the lua stack and calls a lua function afterwards 63 68 template<typename Ret, typename... Args> 64 static Ret callLuaFunction(lua_State *lua, intref, Args... args)69 static void callLuaFunction(lua_State *lua, int *ref, Args... args) 65 70 { 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 67 78 // We pass one extra argument in case the function has no arguments at all 68 79 pushArgumentsToLuaStack<Args...>(lua, args..., false); 69 int r = lua_pcall(lua, 1, sizeof...(args), 0);80 lua_pcall(lua, sizeof...(args), 0, 0); 70 81 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 } 77 86 78 // TODO79 return Ret();80 }81 87 // This is needed in case the function has no arguments at all. Otherwise, we 82 88 // would have a missing argument for such function. This is also why we pass … … 97 103 template<typename T> 98 104 static void pushToLuaStack(lua_State *lua, T value); 105 106 static std::list<std::unique_ptr<int> > callbackRefs; 99 107 }; 100 108 -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
r11549 r11552 82 82 { 83 83 this->timeouts.push_back(std::make_pair(callback, static_cast<float>(timeout))); 84 orxout(user_warning) << "Calling should work..." << std::endl;85 callback();86 84 } 87 85 … … 95 93 if(timeout->second <= 0) 96 94 { 97 orxout(user_warning) << "Calling..." << std::endl;98 95 timeout->first(); 99 96 timeout = this->timeouts.erase(timeout); -
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
r11549 r11552 1 1 2 2 #include "scriptable_controller_api.h" 3 #include <chrono>4 #include "lua.hpp"5 3 #include "luatb.h" 6 4 #include "scriptable_controller.h" … … 30 28 void ScriptableControllerAPI::registerAfterTimeout(std::function<void (void)> callback, double timeout) 31 29 { 30 // TODO Extend timer class to accept std::function 32 31 this->controller_->registerTimeout(callback, timeout); 33 32 } … … 35 34 int ScriptableControllerAPI::registerAtNearObject(std::function<void (int, int)> callback, int obj1, int obj2, double distance) 36 35 { 37 orxout(user_warning) << "Working!" << std::endl; 36 38 37 } 39 38
Note: See TracChangeset
for help on using the changeset viewer.