diff --git a/src/core_defs.h b/src/core_defs.h index 789d2100..eb0e9e25 100644 --- a/src/core_defs.h +++ b/src/core_defs.h @@ -8,7 +8,7 @@ inline const std::string CORE_AIR = "core:air"; inline const std::string TEXTURE_NOTFOUND = "notfound"; -/* bindings used in engine code */ +// bindings used in engine code inline const std::string BIND_MOVE_FORWARD = "movement.forward"; inline const std::string BIND_MOVE_BACK = "movement.back"; inline const std::string BIND_MOVE_LEFT = "movement.left"; diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 6e534773..900bb14a 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -7,6 +7,8 @@ #include "../../../debug/Logger.hpp" #include "../../../util/stringutil.h" +inline std::string LAMBDAS_TABLE = "$L"; + static debug::Logger logger("lua-state"); lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { @@ -54,6 +56,9 @@ lua::LuaState::LuaState() { lua_pushvalue(L, LUA_GLOBALSINDEX); setglobal(envName(0)); + + lua_createtable(L, 0, 0); + setglobal(LAMBDAS_TABLE); } const std::string lua::LuaState::envName(int env) { @@ -65,7 +70,7 @@ lua::LuaState::~LuaState() { } void lua::LuaState::logError(const std::string& text) { - std::cerr << text << std::endl; + logger.error() << text; } void lua::LuaState::addfunc(const std::string& name, lua_CFunction func) { @@ -366,6 +371,28 @@ const std::string lua::LuaState::storeAnonymous() { return funcName; } +runnable lua::LuaState::createLambda() { + auto ptr = reinterpret_cast(lua_topointer(L, -1)); + auto name = util::mangleid(ptr); + lua_getglobal(L, LAMBDAS_TABLE.c_str()); + lua_pushvalue(L, -2); + lua_setfield(L, -2, name.c_str()); + lua_pop(L, 2); + + std::shared_ptr funcptr(new std::string(name), [=](auto* name) { + lua_getglobal(L, LAMBDAS_TABLE.c_str()); + lua_pushnil(L); + lua_setfield(L, -2, name->c_str()); + lua_pop(L, 1); + delete name; + }); + return [=]() { + lua_getglobal(L, LAMBDAS_TABLE.c_str()); + lua_getfield(L, -1, funcptr->c_str()); + lua_call(L, 0, LUA_MULTRET); + }; +} + int lua::LuaState::createEnvironment(int parent) { int id = nextEnvironment++; @@ -396,7 +423,7 @@ void lua::LuaState::removeEnvironment(int id) { } lua_pushnil(L); setglobal(envName(id)); - logger.info() << "removed environment " << envName(id); + logger.debug() << "removed environment " << envName(id); } void lua::LuaState::dumpStack() { diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index dce2e685..5c6531e1 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -6,6 +6,7 @@ #include #include "../../../data/dynamic.h" +#include "../../../delegates.h" #ifndef LUAJIT_VERSION #error LuaJIT required @@ -62,6 +63,7 @@ namespace lua { bool hasglobal(const std::string& name); bool rename(const std::string& from, const std::string& to); void remove(const std::string& name);; + runnable createLambda(); int createEnvironment(int parent); void removeEnvironment(int id); const std::string storeAnonymous(); diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index a68eab4d..5da8d323 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -3,12 +3,15 @@ #include #include "lua/LuaState.h" +#include "../../debug/Logger.hpp" #include "../../util/stringutil.h" namespace scripting { extern lua::LuaState* state; } +static debug::Logger logger("scripting_func"); + using namespace scripting; runnable scripting::create_runnable( @@ -16,13 +19,13 @@ runnable scripting::create_runnable( const std::string& src, const std::string& file ) { - return [=](){ - try { - state->execute(*env, src, file); - } catch (const lua::luaerror& err) { - std::cerr << err.what() << std::endl; - } - }; + try { + state->loadbuffer(*env, src, file); + return state->createLambda(); + } catch (const lua::luaerror& err) { + logger.error() << err.what(); + return [](){}; + } } static bool processCallback(