[Orxonox-commit 6931] r11552 - code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller
kohlia at orxonox.net
kohlia at orxonox.net
Tue Nov 7 19:26:12 CET 2017
Author: kohlia
Date: 2017-11-07 19:26:12 +0100 (Tue, 07 Nov 2017)
New Revision: 11552
Modified:
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
Log:
Lua bindings should work now
Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp 2017-11-07 16:47:14 UTC (rev 11551)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb.ipp 2017-11-07 18:26:12 UTC (rev 11552)
@@ -44,7 +44,6 @@
std::cerr << "ERROR: LuaTB: Lua script called a function with wrong number of arguments (" << argc << " given, " << sizeof...(Args) << " expected)" << std::endl;
return LUA_ERRSYNTAX;
}
- orxonox::orxout(orxonox::user_warning) << "what" << std::endl;
// Call getArgument for every argument seperately to convert each argument
// to the correct type and call the function afterwards
Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc 2017-11-07 16:47:14 UTC (rev 11551)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.cc 2017-11-07 18:26:12 UTC (rev 11552)
@@ -3,18 +3,21 @@
#include "luatb.h"
#include <string>
+// Holds a list of all current callback references
+std::list<std::unique_ptr<int> > LuaTBTypedStack::callbackRefs = {};
+
// Explicit and full specializations need to be in a .cpp file
template<>
-int LuaTBTypedStack::popFromLuaStack<int>(lua_State *lua)
+int LuaTBTypedStack::getFromLuaStack<int>(lua_State *lua)
{ return lua_tointeger(lua, lua_gettop(lua)); }
template<>
-double LuaTBTypedStack::popFromLuaStack<double>(lua_State *lua)
+double LuaTBTypedStack::getFromLuaStack<double>(lua_State *lua)
{ return lua_tonumber(lua, lua_gettop(lua)); }
template<>
-std::string LuaTBTypedStack::popFromLuaStack<std::string>(lua_State *lua)
+std::string LuaTBTypedStack::getFromLuaStack<std::string>(lua_State *lua)
{ return lua_tostring(lua, lua_gettop(lua)); }
template<>
Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h 2017-11-07 16:47:14 UTC (rev 11551)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/luatb_typed_stack.h 2017-11-07 18:26:12 UTC (rev 11552)
@@ -13,71 +13,77 @@
class LuaTBTypedStack
{
public:
- // Get an argument from the lua stack and convert it to type 'T'
+
+ // Get a non-function argument from the lua stack and convert it to type 'T'
+ // Pops the value from the stack.
template<typename T>
- static T getArgument(lua_State *lua)
+ static typename std::enable_if<!IsCallable<T>::value, T>::type getArgument(lua_State *lua)
{
- T value = LuaTBTypedStack::popFromLuaStack<T>(lua);
+ T value = LuaTBTypedStack::getFromLuaStack<T>(lua);
lua_pop(lua, 1);
return value;
}
-private:
- // Gets the top element of the lua stack and converts it to the appropriate
- // type. Only works for certain types, if 'T' is none of these types, you'll
- // get an error.
- template<typename T>
- static typename std::enable_if<!IsCallable<T>::value, T>::type popFromLuaStack(lua_State *lua);
-
// Specialization if 'T' is a callable type (std::function). Saves the lua
// function in the registry and constructs a function to call it again.
// 'decltype(&T::operator())' represents the function signature of the callable
// object.
template<typename T>
- static typename std::enable_if<IsCallable<T>::value, T>::type popFromLuaStack(lua_State *lua)
+ static typename std::enable_if<IsCallable<T>::value, T>::type getArgument(lua_State *lua)
{
- return GetLuaCallback<decltype(&T::operator())>::value(lua, luaL_ref(lua, LUA_REGISTRYINDEX));
+ // Here's the tricky part. Apparently, references in the registry can only
+ // be called once. This is why we always have to re-add it to the registry
+ // after every call. That means, we need a persistent variable for 'ref' and
+ // that's only possible with a pointer in this case.
+ int *ref = new int(luaL_ref(lua, LUA_REGISTRYINDEX));
+ LuaTBTypedStack::callbackRefs.push_back(std::unique_ptr<int>(ref));
+
+ return GetLuaCallback<decltype(&T::operator())>::value(lua, ref);
}
- // Get a function that will call a lua callback
+private:
template<typename T> struct GetLuaCallback;
+ // Gets a value from the top of the lua stack and returns it with the proper type.
+ // Does not pop the value!
+ template<typename T> static T getFromLuaStack(lua_State *lua);
+
// This class is only valid for std::function types. The type argument will not
// be a normal function signature because it is the signature of
// std::function<>::operator(), which is also the reason for the 'const'.
template<typename Ret, typename... Args>
- struct GetLuaCallback<Ret(std::function<Ret(Args...)>::*)(Args...) const>
+ struct GetLuaCallback<void (std::function<Ret(Args...)>::*)(Args...) const>
{
// Returns a lambda that will push the arguments to the lua stack and call
// the function afterwards. We can't return 'callLuaFunction' directly,
// because we need the additional arguments 'lua' and 'ref' which we would
// like to hide from the user.
- static std::function<Ret (Args...)> value(lua_State *lua, int ref)
+ static std::function<void (Args...)> value(lua_State *lua, int *ref)
{
- orxonox::orxout(orxonox::user_warning) << "Ref1: " << ref << std::endl;
- return [lua, ref](Args... args){return callLuaFunction<Ret, Args...>(lua, ref, args...);};
+ return [lua, ref](Args... args){callLuaFunction<Ret, Args...>(lua, ref, args...);};
}
};
// Pushes all arguments to the lua stack and calls a lua function afterwards
template<typename Ret, typename... Args>
- static Ret callLuaFunction(lua_State *lua, int ref, Args... args)
+ static void callLuaFunction(lua_State *lua, int *ref, Args... args)
{
- lua_rawgeti(lua, LUA_REGISTRYINDEX, ref);
+ // Get the value of the callback from the registry and push it to the stack
+ lua_rawgeti(lua, LUA_REGISTRYINDEX, *ref);
+
+ // Duplicate it on the stack so we can save it in the registry again after
+ // we called the callback.
+ lua_pushvalue(lua, 1);
+
// We pass one extra argument in case the function has no arguments at all
pushArgumentsToLuaStack<Args...>(lua, args..., false);
- int r = lua_pcall(lua, 1, sizeof...(args), 0);
+ lua_pcall(lua, sizeof...(args), 0, 0);
- orxonox::orxout(orxonox::user_warning) << "Ref2: " << ref << std::endl;
-if(r != 0){
- const char* message = lua_tostring(lua, -1);
- std::cout << message << std::endl;
- lua_pop(lua, 1);
-}
+ // Release the old reference and save the function in the registry again
+ lua_unref(lua, *ref);
+ *ref = luaL_ref(lua, LUA_REGISTRYINDEX);
+ }
- // TODO
- return Ret();
- }
// This is needed in case the function has no arguments at all. Otherwise, we
// would have a missing argument for such function. This is also why we pass
// a dummy argument in 'callLuaFunction', so we have at least one argument.
@@ -96,6 +102,8 @@
// Pushes a value to the lua stack. Only the specializations are valid.
template<typename T>
static void pushToLuaStack(lua_State *lua, T value);
+
+ static std::list<std::unique_ptr<int> > callbackRefs;
};
#endif // LUATB_TYPED_STACK_H
Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc 2017-11-07 16:47:14 UTC (rev 11551)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller.cc 2017-11-07 18:26:12 UTC (rev 11552)
@@ -81,8 +81,6 @@
void ScriptableController::registerTimeout(std::function<void ()> callback, double timeout)
{
this->timeouts.push_back(std::make_pair(callback, static_cast<float>(timeout)));
- orxout(user_warning) << "Calling should work..." << std::endl;
- callback();
}
void ScriptableController::tick(float dt)
@@ -94,7 +92,6 @@
timeout->second -= dt;
if(timeout->second <= 0)
{
- orxout(user_warning) << "Calling..." << std::endl;
timeout->first();
timeout = this->timeouts.erase(timeout);
}
Modified: code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc
===================================================================
--- code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc 2017-11-07 16:47:14 UTC (rev 11551)
+++ code/branches/ScriptableController_HS17/src/orxonox/scriptablecontroller/scriptable_controller_api.cc 2017-11-07 18:26:12 UTC (rev 11552)
@@ -1,7 +1,5 @@
#include "scriptable_controller_api.h"
-#include <chrono>
-#include "lua.hpp"
#include "luatb.h"
#include "scriptable_controller.h"
@@ -29,12 +27,13 @@
void ScriptableControllerAPI::registerAfterTimeout(std::function<void (void)> callback, double timeout)
{
+ // TODO Extend timer class to accept std::function
this->controller_->registerTimeout(callback, timeout);
}
int ScriptableControllerAPI::registerAtNearObject(std::function<void (int, int)> callback, int obj1, int obj2, double distance)
{
- orxout(user_warning) << "Working!" << std::endl;
+
}
int ScriptableControllerAPI::registerAtAreaEnter(std::function<void (int)> callback, int obj, int x, int y, int z, int dx, int dy, int dz)
More information about the Orxonox-commit
mailing list