From 0647bc6f904971214c81e252d19d141734966996 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 11 Jun 2024 03:37:35 +0300 Subject: [PATCH] refactor: 'lua' namespace expansion --- src/logic/scripting/lua/LuaState.cpp | 170 +------------------ src/logic/scripting/lua/LuaState.hpp | 21 --- src/logic/scripting/lua/api_lua.hpp | 2 +- src/logic/scripting/lua/libaudio.cpp | 51 +++--- src/logic/scripting/lua/libblock.cpp | 48 +++--- src/logic/scripting/lua/libconsole.cpp | 22 +-- src/logic/scripting/lua/libcore.cpp | 53 +++--- src/logic/scripting/lua/libfile.cpp | 44 ++--- src/logic/scripting/lua/libgui.cpp | 89 +++++----- src/logic/scripting/lua/libhud.cpp | 23 ++- src/logic/scripting/lua/libinput.cpp | 17 +- src/logic/scripting/lua/libinventory.cpp | 113 ++++++------ src/logic/scripting/lua/libitem.cpp | 32 ++-- src/logic/scripting/lua/libjson.cpp | 19 +-- src/logic/scripting/lua/libpack.cpp | 75 ++++---- src/logic/scripting/lua/libplayer.cpp | 102 +++++------ src/logic/scripting/lua/libtime.cpp | 13 +- src/logic/scripting/lua/libtoml.cpp | 16 +- src/logic/scripting/lua/libworld.cpp | 47 +++-- src/logic/scripting/lua/lua_commons.cpp | 9 + src/logic/scripting/lua/lua_commons.hpp | 29 ++-- src/logic/scripting/lua/lua_util.cpp | 120 ++++++++++++- src/logic/scripting/lua/lua_util.hpp | 149 ++++++++++++---- src/logic/scripting/scripting.cpp | 37 ++-- src/logic/scripting/scripting_functional.cpp | 27 ++- src/logic/scripting/scripting_hud.cpp | 8 +- 26 files changed, 613 insertions(+), 723 deletions(-) create mode 100644 src/logic/scripting/lua/lua_commons.cpp diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 0d70a378..3321fe7e 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -8,16 +8,10 @@ #include #include -inline std::string LAMBDAS_TABLE = "$L"; - static debug::Logger logger("lua-state"); using namespace lua; -namespace scripting { - extern LuaState* state; -} - luaerror::luaerror(const std::string& message) : std::runtime_error(message) { } @@ -63,16 +57,12 @@ LuaState::LuaState() { createLibs(L); pushglobals(L); - setglobal(L, envName(0)); + setglobal(L, env_name(0)); lua_createtable(L, 0, 0); setglobal(L, LAMBDAS_TABLE); } -std::string LuaState::envName(int env) { - return "_ENV"+util::mangleid(env); -} - LuaState::~LuaState() { lua_close(mainThread); } @@ -82,26 +72,6 @@ void LuaState::addfunc(lua_State* L, const std::string& name, lua_CFunction func lua_setglobal(L, name.c_str()); } -bool LuaState::rename(lua_State* L, const std::string& from, const std::string& to) { - const char* src = from.c_str(); - lua_getglobal(L, src); - if (lua_isnil(L, lua_gettop(L))) { - lua_pop(L, lua_gettop(L)); - return false; - } - lua_setglobal(L, to.c_str()); - - // remove previous - lua_pushnil(L); - lua_setglobal(L, src); - return true; -} - -void LuaState::remove(lua_State* L, const std::string& name) { - lua_pushnil(L); - lua_setglobal(L, name.c_str()); -} - void LuaState::createLibs(lua_State* L) { openlib(L, "audio", audiolib); openlib(L, "block", blocklib); @@ -119,34 +89,7 @@ void LuaState::createLibs(lua_State* L) { openlib(L, "toml", tomllib); openlib(L, "world", worldlib); - addfunc(L, "print", lua_wrap_errors); -} - -void LuaState::loadbuffer(lua_State* L, int env, const std::string& src, const std::string& file) { - if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) { - throw luaerror(lua_tostring(L, -1)); - } - if (env && getglobal(L, envName(env))) { - lua_setfenv(L, -2); - } -} - -int LuaState::eval(lua_State* L, int env, const std::string& src, const std::string& file) { - auto srcText = "return "+src; - loadbuffer(L, env, srcText, file); - return call(L, 0); -} - -int LuaState::execute(lua_State* L, int env, const std::string& src, const std::string& file) { - loadbuffer(L, env, src, file); - return callNoThrow(L, 0); -} - -int LuaState::pushenv(lua_State* L, int env) { - if (getglobal(L, envName(env))) { - return 1; - } - return 0; + addfunc(L, "print", lua::wrap); } void LuaState::openlib(lua_State* L, const std::string& name, const luaL_Reg* libfuncs) { @@ -155,117 +98,16 @@ void LuaState::openlib(lua_State* L, const std::string& name, const luaL_Reg* li lua_setglobal(L, name.c_str()); } -std::shared_ptr LuaState::createLambdaHandler(lua_State* L) { - 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); - - return std::shared_ptr(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; - }); -} - -runnable LuaState::createRunnable(lua_State* L) { - auto funcptr = createLambdaHandler(L); - return [=]() { - lua_getglobal(L, LAMBDAS_TABLE.c_str()); - lua_getfield(L, -1, funcptr->c_str()); - callNoThrow(L, 0); - }; -} - -scripting::common_func LuaState::createLambda(lua_State* L) { - auto funcptr = createLambdaHandler(L); - return [=](const std::vector& args) { - lua_getglobal(L, LAMBDAS_TABLE.c_str()); - lua_getfield(L, -1, funcptr->c_str()); - for (const auto& arg : args) { - pushvalue(L, arg); - } - if (call(L, args.size(), 1)) { - auto result = tovalue(L, -1); - lua_pop(L, 1); - return result; - } - return dynamic::Value(dynamic::NONE); - }; -} - -int LuaState::createEnvironment(lua_State* L, int parent) { - int id = nextEnvironment++; - - // local env = {} - lua_createtable(L, 0, 1); - - // setmetatable(env, {__index=_G}) - lua_createtable(L, 0, 1); - if (parent == 0) { - lua_pushvalue(L, LUA_GLOBALSINDEX); - } else { - if (pushenv(L, parent) == 0) { - lua_pushvalue(L, LUA_GLOBALSINDEX); - } - } - lua_setfield(L, -2, "__index"); - lua_setmetatable(L, -2); - - // envname = env - setglobal(L, envName(id)); - return id; -} - - -void LuaState::removeEnvironment(lua_State* L, int id) { - if (id == 0) { - return; - } - lua_pushnil(L); - setglobal(L, envName(id)); -} - bool LuaState::emitEvent(lua_State* L, const std::string &name, std::function args) { getglobal(L, "events"); getfield(L, "emit"); - lua::pushstring(L, name); - callNoThrow(L, args(L) + 1); - bool result = lua_toboolean(L, -1); - lua_pop(L, 2); + pushstring(L, name); + call_nothrow(L, args(L) + 1); + bool result = toboolean(L, -1); + pop(L, 2); return result; } - -void LuaState::dumpStack(lua_State* L) { - int top = lua_gettop(L); - for (int i = 1; i <= top; i++) { - std::cout << std::setw(3) << i << std::setw(20) << luaL_typename(L, i) << std::setw(30); - switch (lua_type(L, i)) { - case LUA_TNUMBER: - std::cout << lua_tonumber(L, i); - break; - case LUA_TSTRING: - std::cout << lua_tostring(L, i); - break; - case LUA_TBOOLEAN: - std::cout << (lua_toboolean(L, i) ? "true" : "false"); - break; - case LUA_TNIL: - std::cout << "nil"; - break; - default: - std::cout << lua_topointer(L, i); - break; - } - std::cout << std::endl; - } -} - lua_State* LuaState::getMainThread() const { return mainThread; } diff --git a/src/logic/scripting/lua/LuaState.hpp b/src/logic/scripting/lua/LuaState.hpp index f8a925e5..2d724373 100644 --- a/src/logic/scripting/lua/LuaState.hpp +++ b/src/logic/scripting/lua/LuaState.hpp @@ -11,40 +11,19 @@ #include namespace lua { - class luaerror : public std::runtime_error { - public: - luaerror(const std::string& message); - }; - class LuaState { lua_State* mainThread; - int nextEnvironment = 1; - void removeLibFuncs(lua_State*, const char* libname, const char* funcs[]); void createLibs(lua_State* L); - - std::shared_ptr createLambdaHandler(lua_State*); public: LuaState(); ~LuaState(); - static std::string envName(int env); - void loadbuffer(lua_State*, int env, const std::string& src, const std::string& file); - int pushenv(lua_State*, int env); - int execute(lua_State*, int env, const std::string& src, const std::string& file=""); - int eval(lua_State*, int env, const std::string& src, const std::string& file=""); void openlib(lua_State*, const std::string& name, const luaL_Reg* libfuncs); void addfunc(lua_State*, const std::string& name, lua_CFunction func); - bool rename(lua_State*, const std::string& from, const std::string& to); - void remove(lua_State*, const std::string& name);; - runnable createRunnable(lua_State*); - scripting::common_func createLambda(lua_State*); - int createEnvironment(lua_State*, int parent); - void removeEnvironment(lua_State*, int id); bool emitEvent(lua_State*, const std::string& name, std::function args=[](auto*){return 0;}); - void dumpStack(lua_State*); lua_State* getMainThread() const; }; } diff --git a/src/logic/scripting/lua/api_lua.hpp b/src/logic/scripting/lua/api_lua.hpp index 69526057..c1ff9ebf 100644 --- a/src/logic/scripting/lua/api_lua.hpp +++ b/src/logic/scripting/lua/api_lua.hpp @@ -1,7 +1,7 @@ #ifndef LOGIC_SCRIPTING_API_LUA_HPP_ #define LOGIC_SCRIPTING_API_LUA_HPP_ -#include "lua_commons.hpp" +#include "lua_util.hpp" #include diff --git a/src/logic/scripting/lua/libaudio.cpp b/src/logic/scripting/lua/libaudio.cpp index 833b00ae..9db10d3a 100644 --- a/src/logic/scripting/lua/libaudio.cpp +++ b/src/logic/scripting/lua/libaudio.cpp @@ -1,10 +1,7 @@ #include "api_lua.hpp" -#include "lua_commons.hpp" -#include "lua_util.hpp" #include "../../../audio/audio.hpp" #include "../../../engine.hpp" -#include "../scripting.hpp" inline const char* DEFAULT_CHANNEL = "regular"; @@ -386,29 +383,29 @@ static int l_audio_count_streams(lua_State* L) { } const luaL_Reg audiolib [] = { - {"play_sound", lua_wrap_errors}, - {"play_sound_2d", lua_wrap_errors}, - {"play_stream", lua_wrap_errors}, - {"play_stream_2d", lua_wrap_errors}, - {"stop", lua_wrap_errors}, - {"pause", lua_wrap_errors}, - {"resume", lua_wrap_errors}, - {"set_loop", lua_wrap_errors}, - {"set_volume", lua_wrap_errors}, - {"set_pitch", lua_wrap_errors}, - {"set_time", lua_wrap_errors}, - {"set_position", lua_wrap_errors}, - {"set_velocity", lua_wrap_errors}, - {"is_playing", lua_wrap_errors}, - {"is_paused", lua_wrap_errors}, - {"is_loop", lua_wrap_errors}, - {"get_volume", lua_wrap_errors}, - {"get_pitch", lua_wrap_errors}, - {"get_time", lua_wrap_errors}, - {"get_duration", lua_wrap_errors}, - {"get_position", lua_wrap_errors}, - {"get_velocity", lua_wrap_errors}, - {"count_speakers", lua_wrap_errors}, - {"count_streams", lua_wrap_errors}, + {"play_sound", lua::wrap}, + {"play_sound_2d", lua::wrap}, + {"play_stream", lua::wrap}, + {"play_stream_2d", lua::wrap}, + {"stop", lua::wrap}, + {"pause", lua::wrap}, + {"resume", lua::wrap}, + {"set_loop", lua::wrap}, + {"set_volume", lua::wrap}, + {"set_pitch", lua::wrap}, + {"set_time", lua::wrap}, + {"set_position", lua::wrap}, + {"set_velocity", lua::wrap}, + {"is_playing", lua::wrap}, + {"is_paused", lua::wrap}, + {"is_loop", lua::wrap}, + {"get_volume", lua::wrap}, + {"get_pitch", lua::wrap}, + {"get_time", lua::wrap}, + {"get_duration", lua::wrap}, + {"get_position", lua::wrap}, + {"get_velocity", lua::wrap}, + {"count_speakers", lua::wrap}, + {"count_streams", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libblock.cpp b/src/logic/scripting/lua/libblock.cpp index 8bdafb22..a09aa592 100644 --- a/src/logic/scripting/lua/libblock.cpp +++ b/src/logic/scripting/lua/libblock.cpp @@ -1,8 +1,4 @@ -#include "lua_commons.hpp" - #include "api_lua.hpp" -#include "lua_util.hpp" -#include "../scripting.hpp" #include "../../../world/Level.hpp" #include "../../../voxels/Chunks.hpp" @@ -279,27 +275,27 @@ static int l_caption(lua_State* L) { } const luaL_Reg blocklib [] = { - {"index", lua_wrap_errors}, - {"name", lua_wrap_errors}, - {"material", lua_wrap_errors}, - {"caption", lua_wrap_errors}, - {"defs_count", lua_wrap_errors}, - {"is_solid_at", lua_wrap_errors}, - {"is_replaceable_at", lua_wrap_errors}, - {"set", lua_wrap_errors}, - {"get", lua_wrap_errors}, - {"get_X", lua_wrap_errors}, - {"get_Y", lua_wrap_errors}, - {"get_Z", lua_wrap_errors}, - {"get_states", lua_wrap_errors}, - {"set_states", lua_wrap_errors}, - {"get_rotation", lua_wrap_errors}, - {"set_rotation", lua_wrap_errors}, - {"get_user_bits", lua_wrap_errors}, - {"set_user_bits", lua_wrap_errors}, - {"is_extended", lua_wrap_errors}, - {"get_size", lua_wrap_errors}, - {"is_segment", lua_wrap_errors}, - {"seek_origin", lua_wrap_errors}, + {"index", lua::wrap}, + {"name", lua::wrap}, + {"material", lua::wrap}, + {"caption", lua::wrap}, + {"defs_count", lua::wrap}, + {"is_solid_at", lua::wrap}, + {"is_replaceable_at", lua::wrap}, + {"set", lua::wrap}, + {"get", lua::wrap}, + {"get_X", lua::wrap}, + {"get_Y", lua::wrap}, + {"get_Z", lua::wrap}, + {"get_states", lua::wrap}, + {"set_states", lua::wrap}, + {"get_rotation", lua::wrap}, + {"set_rotation", lua::wrap}, + {"get_user_bits", lua::wrap}, + {"set_user_bits", lua::wrap}, + {"is_extended", lua::wrap}, + {"get_size", lua::wrap}, + {"is_segment", lua::wrap}, + {"seek_origin", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libconsole.cpp b/src/logic/scripting/lua/libconsole.cpp index 0a27bcde..f7eb6cb6 100644 --- a/src/logic/scripting/lua/libconsole.cpp +++ b/src/logic/scripting/lua/libconsole.cpp @@ -1,17 +1,9 @@ #include "api_lua.hpp" -#include "lua_commons.hpp" -#include "lua_util.hpp" -#include "LuaState.hpp" -#include "../scripting.hpp" #include "../../CommandsInterpreter.hpp" #include "../../../engine.hpp" #include "../../../coders/commons.hpp" -namespace scripting { - extern lua::LuaState* state; -} - using namespace scripting; static int l_add_command(lua_State* L) { @@ -20,8 +12,8 @@ static int l_add_command(lua_State* L) { } auto scheme = lua::require_string(L, 1); auto description = lua::require_string(L, 2); - lua_pushvalue(L, 3); - auto func = state->createLambda(L); + lua::pushvalue(L, 3); + auto func = lua::create_lambda(L); try { engine->getCommandsInterpreter()->getRepository()->add( scheme, description, [func](auto, auto args, auto kwargs) { @@ -115,10 +107,10 @@ static int l_get_command_info(lua_State* L) { } const luaL_Reg consolelib [] = { - {"add_command", lua_wrap_errors}, - {"execute", lua_wrap_errors}, - {"set", lua_wrap_errors}, - {"get_commands_list", lua_wrap_errors}, - {"get_command_info", lua_wrap_errors}, + {"add_command", lua::wrap}, + {"execute", lua::wrap}, + {"set", lua::wrap}, + {"get_commands_list", lua::wrap}, + {"get_command_info", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libcore.cpp b/src/logic/scripting/lua/libcore.cpp index 48003a7d..eb98cca3 100644 --- a/src/logic/scripting/lua/libcore.cpp +++ b/src/logic/scripting/lua/libcore.cpp @@ -1,7 +1,4 @@ -#include "lua_commons.hpp" -#include "lua_util.hpp" #include "api_lua.hpp" -#include "LuaState.hpp" #include "../../../engine.hpp" #include "../../../files/settings_io.hpp" @@ -14,14 +11,10 @@ #include "../../../window/Events.hpp" #include "../../../window/Window.hpp" #include "../../../world/WorldGenerators.hpp" -#include "../scripting.hpp" #include #include -namespace scripting { - extern lua::LuaState* state; -} using namespace scripting; static int l_new_world(lua_State* L) { @@ -128,17 +121,17 @@ static int l_get_setting_info(lua_State* L) { auto setting = engine->getSettingsHandler().getSetting(name); lua_createtable(L, 0, 1); if (auto number = dynamic_cast(setting)) { - lua_pushnumber(L, number->getMin()); - lua_setfield(L, -2, "min"); - lua_pushnumber(L, number->getMax()); - lua_setfield(L, -2, "max"); + lua::pushnumber(L, number->getMin()); + lua::setfield(L, "min"); + lua::pushnumber(L, number->getMax()); + lua::setfield(L, "max"); return 1; } if (auto integer = dynamic_cast(setting)) { - lua_pushinteger(L, integer->getMin()); - lua_setfield(L, -2, "min"); - lua_pushinteger(L, integer->getMax()); - lua_setfield(L, -2, "max"); + lua::pushinteger(L, integer->getMin()); + lua::setfield(L, "min"); + lua::pushinteger(L, integer->getMax()); + lua::setfield(L, "max"); return 1; } lua_pop(L, 1); @@ -151,7 +144,7 @@ static int l_quit(lua_State*) { } static int l_get_default_generator(lua_State* L) { - lua_pushstring(L, WorldGenerators::getDefaultGeneratorID().c_str()); + lua::pushstring(L, WorldGenerators::getDefaultGeneratorID().c_str()); return 1; } @@ -161,7 +154,7 @@ static int l_get_generators(lua_State* L) { int i = 0; for (auto& id : generators) { - lua_pushstring(L, id.c_str()); + lua::pushstring(L, id.c_str()); lua_rawseti(L, -2, i + 1); i++; } @@ -169,18 +162,18 @@ static int l_get_generators(lua_State* L) { } const luaL_Reg corelib [] = { - {"new_world", lua_wrap_errors}, - {"open_world", lua_wrap_errors}, - {"reopen_world", lua_wrap_errors}, - {"close_world", lua_wrap_errors}, - {"delete_world", lua_wrap_errors}, - {"reconfig_packs", lua_wrap_errors}, - {"get_setting", lua_wrap_errors}, - {"set_setting", lua_wrap_errors}, - {"str_setting", lua_wrap_errors}, - {"get_setting_info", lua_wrap_errors}, - {"quit", lua_wrap_errors}, - {"get_default_generator", lua_wrap_errors}, - {"get_generators", lua_wrap_errors}, + {"new_world", lua::wrap}, + {"open_world", lua::wrap}, + {"reopen_world", lua::wrap}, + {"close_world", lua::wrap}, + {"delete_world", lua::wrap}, + {"reconfig_packs", lua::wrap}, + {"get_setting", lua::wrap}, + {"set_setting", lua::wrap}, + {"str_setting", lua::wrap}, + {"get_setting_info", lua::wrap}, + {"quit", lua::wrap}, + {"get_default_generator", lua::wrap}, + {"get_generators", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index 85336add..b9477c4b 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -1,8 +1,5 @@ -#include "lua_commons.hpp" -#include "lua_util.hpp" #include "api_lua.hpp" -#include "LuaState.hpp" -#include "../scripting.hpp" + #include "../../../engine.hpp" #include "../../../coders/gzip.hpp" #include "../../../files/files.hpp" @@ -13,11 +10,6 @@ #include namespace fs = std::filesystem; - -namespace scripting { - extern lua::LuaState* state; -} - using namespace scripting; static fs::path resolve_path(const std::string& path) { @@ -232,22 +224,22 @@ static int l_file_gzip_decompress(lua_State* L) { } const luaL_Reg filelib [] = { - {"exists", lua_wrap_errors}, - {"find", lua_wrap_errors}, - {"isdir", lua_wrap_errors}, - {"isfile", lua_wrap_errors}, - {"length", lua_wrap_errors}, - {"list", lua_wrap_errors}, - {"mkdir", lua_wrap_errors}, - {"mkdirs", lua_wrap_errors}, - {"read_bytes", lua_wrap_errors}, - {"read", lua_wrap_errors}, - {"remove", lua_wrap_errors}, - {"remove_tree", lua_wrap_errors}, - {"resolve", lua_wrap_errors}, - {"write_bytes", lua_wrap_errors}, - {"write", lua_wrap_errors}, - {"gzip_compress", lua_wrap_errors}, - {"gzip_decompress", lua_wrap_errors}, + {"exists", lua::wrap}, + {"find", lua::wrap}, + {"isdir", lua::wrap}, + {"isfile", lua::wrap}, + {"length", lua::wrap}, + {"list", lua::wrap}, + {"mkdir", lua::wrap}, + {"mkdirs", lua::wrap}, + {"read_bytes", lua::wrap}, + {"read", lua::wrap}, + {"remove", lua::wrap}, + {"remove_tree", lua::wrap}, + {"resolve", lua::wrap}, + {"write_bytes", lua::wrap}, + {"write", lua::wrap}, + {"gzip_compress", lua::wrap}, + {"gzip_decompress", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index e89b1046..c61611bd 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -1,9 +1,5 @@ -#include "lua_commons.hpp" #include "api_lua.hpp" -#include "lua_util.hpp" -#include "LuaState.hpp" -#include "../scripting.hpp" #include "../../../engine.hpp" #include "../../../assets/Assets.hpp" #include "../../../items/Inventories.hpp" @@ -23,18 +19,13 @@ #include "../../../world/Level.hpp" using namespace gui; - -namespace scripting { - extern lua::LuaState* state; -} +using namespace scripting; struct DocumentNode { UiDocument* document; std::shared_ptr node; }; -using namespace scripting; - static DocumentNode getDocumentNode(lua_State*, const std::string& name, const std::string& nodeName) { auto doc = engine->getAssets()->getLayout(name); if (doc == nullptr) { @@ -115,10 +106,10 @@ static int l_container_clear(lua_State* L) { static int l_container_set_interval(lua_State* L) { auto node = getDocumentNode(L, 1); - auto interval = lua_tointeger(L, 2) / 1000.0f; + auto interval = lua::tointeger(L, 2) / 1000.0f; if (auto container = std::dynamic_pointer_cast(node.node)) { - lua_pushvalue(L, 3); - auto runnable = state->createRunnable(L); + lua::pushvalue(L, 3); + auto runnable = lua::create_runnable(L); container->listenInterval(interval, runnable); } return 0; @@ -266,25 +257,25 @@ static int p_get_src(UINode* node, lua_State* L) { static int p_get_add(UINode* node, lua_State* L) { if (dynamic_cast(node)) { - return lua::pushcfunction(L, lua_wrap_errors); + return lua::pushcfunction(L, lua::wrap); } return 0; } static int p_get_destruct(UINode*, lua_State* L) { - return lua::pushcfunction(L, lua_wrap_errors); + return lua::pushcfunction(L, lua::wrap); } static int p_get_clear(UINode* node, lua_State* L) { if (dynamic_cast(node)) { - return lua::pushcfunction(L, lua_wrap_errors); + return lua::pushcfunction(L, lua::wrap); } return 0; } static int p_set_interval(UINode* node, lua_State* L) { if (dynamic_cast(node)) { - return lua::pushcfunction(L, lua_wrap_errors); + return lua::pushcfunction(L, lua::wrap); } return 0; } @@ -393,7 +384,7 @@ static void p_set_tooltip(UINode* node, lua_State* L, int idx) { node->setTooltip(lua::require_wstring(L, idx)); } static void p_set_tooltip_delay(UINode* node, lua_State* L, int idx) { - node->setTooltipDelay(lua_tonumber(L, idx)); + node->setTooltipDelay(lua::tonumber(L, idx)); } static void p_set_pos(UINode* node, lua_State* L, int idx) { node->setPos(lua::tovec2(L, idx)); @@ -405,13 +396,13 @@ static void p_set_size(UINode* node, lua_State* L, int idx) { node->setSize(lua::tovec2(L, idx)); } static void p_set_interactive(UINode* node, lua_State* L, int idx) { - node->setInteractive(lua_toboolean(L, idx)); + node->setInteractive(lua::toboolean(L, idx)); } static void p_set_visible(UINode* node, lua_State* L, int idx) { - node->setVisible(lua_toboolean(L, idx)); + node->setVisible(lua::toboolean(L, idx)); } static void p_set_enabled(UINode* node, lua_State* L, int idx) { - node->setEnabled(lua_toboolean(L, idx)); + node->setEnabled(lua::toboolean(L, idx)); } static void p_set_placeholder(UINode* node, lua_State* L, int idx) { if (auto box = dynamic_cast(node)) { @@ -429,12 +420,12 @@ static void p_set_text(UINode* node, lua_State* L, int idx) { } static void p_set_caret(UINode* node, lua_State* L, int idx) { if (auto box = dynamic_cast(node)) { - box->setCaret(static_cast(lua_tointeger(L, idx))); + box->setCaret(static_cast(lua::tointeger(L, idx))); } } static void p_set_editable(UINode* node, lua_State* L, int idx) { if (auto box = dynamic_cast(node)) { - box->setEditable(lua_toboolean(L, idx)); + box->setEditable(lua::toboolean(L, idx)); } } static void p_set_src(UINode* node, lua_State* L, int idx) { @@ -444,27 +435,27 @@ static void p_set_src(UINode* node, lua_State* L, int idx) { } static void p_set_value(UINode* node, lua_State* L, int idx) { if (auto bar = dynamic_cast(node)) { - bar->setValue(lua_tonumber(L, idx)); + bar->setValue(lua::tonumber(L, idx)); } } static void p_set_min(UINode* node, lua_State* L, int idx) { if (auto bar = dynamic_cast(node)) { - bar->setMin(lua_tonumber(L, idx)); + bar->setMin(lua::tonumber(L, idx)); } } static void p_set_max(UINode* node, lua_State* L, int idx) { if (auto bar = dynamic_cast(node)) { - bar->setMax(lua_tonumber(L, idx)); + bar->setMax(lua::tonumber(L, idx)); } } static void p_set_step(UINode* node, lua_State* L, int idx) { if (auto bar = dynamic_cast(node)) { - bar->setStep(lua_tonumber(L, idx)); + bar->setStep(lua::tonumber(L, idx)); } } static void p_set_track_width(UINode* node, lua_State* L, int idx) { if (auto bar = dynamic_cast(node)) { - bar->setTrackWidth(lua_tointeger(L, idx)); + bar->setTrackWidth(lua::tointeger(L, idx)); } } static void p_set_track_color(UINode* node, lua_State* L, int idx) { @@ -474,9 +465,9 @@ static void p_set_track_color(UINode* node, lua_State* L, int idx) { } static void p_set_checked(UINode* node, lua_State* L, int idx) { if (auto box = dynamic_cast(node)) { - box->setChecked(lua_toboolean(L, idx)); + box->setChecked(lua::toboolean(L, idx)); } else if (auto box = dynamic_cast(node)) { - box->setChecked(lua_toboolean(L, idx)); + box->setChecked(lua::toboolean(L, idx)); } } static void p_set_page(UINode* node, lua_State* L, int idx) { @@ -486,7 +477,7 @@ static void p_set_page(UINode* node, lua_State* L, int idx) { } static void p_set_inventory(UINode* node, lua_State* L, int idx) { if (auto view = dynamic_cast(node)) { - auto inventory = level->inventories->get(lua_tointeger(L, idx)); + auto inventory = level->inventories->get(lua::tointeger(L, idx)); if (inventory == nullptr) { view->unbind(); } else { @@ -495,8 +486,8 @@ static void p_set_inventory(UINode* node, lua_State* L, int idx) { } } static void p_set_focused(const std::shared_ptr &node, lua_State* L, int idx) { - if (lua_toboolean(L, idx) && !node->isFocused()) { - scripting::engine->getGUI()->setFocus(node); + if (lua::toboolean(L, idx) && !node->isFocused()) { + engine->getGUI()->setFocus(node); } else if (node->isFocused()){ node->defocus(); } @@ -553,11 +544,11 @@ static int l_gui_setattr(lua_State* L) { static int l_gui_get_env(lua_State* L) { auto name = lua::require_string(L, 1); - auto doc = scripting::engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->getLayout(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } - lua_getglobal(L, lua::LuaState::envName(*doc->getEnvironment()).c_str()); + lua::getglobal(L, lua::env_name(*doc->getEnvironment())); return 1; } @@ -565,16 +556,16 @@ static int l_gui_str(lua_State* L) { auto text = lua::require_wstring(L, 1); if (!lua_isnoneornil(L, 2)) { auto context = lua::require_wstring(L, 2); - lua_pushstring(L, util::wstr2str_utf8(langs::get(text, context)).c_str()); + lua::pushwstring(L, langs::get(text, context)); } else { - lua_pushstring(L, util::wstr2str_utf8(langs::get(text)).c_str()); + lua::pushwstring(L, langs::get(text)); } return 1; } static int l_gui_reindex(lua_State* L) { auto name = lua::require_string(L, 1); - auto doc = scripting::engine->getAssets()->getLayout(name); + auto doc = engine->getAssets()->getLayout(name); if (doc == nullptr) { throw std::runtime_error("document '"+std::string(name)+"' not found"); } @@ -588,24 +579,24 @@ static int l_gui_get_locales_info(lua_State* L) { lua_createtable(L, 0, locales.size()); for (auto& entry : locales) { lua_createtable(L, 0, 1); - lua_pushstring(L, entry.second.name.c_str()); - lua_setfield(L, -2, "name"); - lua_setfield(L, -2, entry.first.c_str()); + lua::pushstring(L, entry.second.name); + lua::setfield(L, "name"); + lua::setfield(L, entry.first); } return 1; } static int l_gui_getviewport(lua_State* L) { - return lua::pushvec2_arr(L, scripting::engine->getGUI()->getContainer()->getSize()); + return lua::pushvec2_arr(L, engine->getGUI()->getContainer()->getSize()); } const luaL_Reg guilib [] = { - {"get_viewport", lua_wrap_errors}, - {"getattr", lua_wrap_errors}, - {"setattr", lua_wrap_errors}, - {"get_env", lua_wrap_errors}, - {"str", lua_wrap_errors}, - {"get_locales_info", lua_wrap_errors}, - {"__reindex", lua_wrap_errors}, + {"get_viewport", lua::wrap}, + {"getattr", lua::wrap}, + {"setattr", lua::wrap}, + {"get_env", lua::wrap}, + {"str", lua::wrap}, + {"get_locales_info", lua::wrap}, + {"__reindex", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index 93d3505b..98a692e5 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -1,6 +1,4 @@ -#include "lua_commons.hpp" #include "api_lua.hpp" -#include "LuaState.hpp" #include "../../../assets/Assets.hpp" #include "../../../content/Content.hpp" @@ -16,7 +14,6 @@ #include "../../../voxels/Chunks.hpp" #include "../../../voxels/voxel.hpp" #include "../../../world/Level.hpp" -#include "../scripting.hpp" #include #include @@ -129,15 +126,15 @@ static int l_hud_get_player(lua_State* L) { } const luaL_Reg hudlib [] = { - {"open_inventory", lua_wrap_errors}, - {"close_inventory", lua_wrap_errors}, - {"open_block", lua_wrap_errors}, - {"open_permanent", lua_wrap_errors}, - {"show_overlay", lua_wrap_errors}, - {"get_block_inventory", lua_wrap_errors}, - {"close", lua_wrap_errors}, - {"pause", lua_wrap_errors}, - {"resume", lua_wrap_errors}, - {"get_player", lua_wrap_errors}, + {"open_inventory", lua::wrap}, + {"close_inventory", lua::wrap}, + {"open_block", lua::wrap}, + {"open_permanent", lua::wrap}, + {"show_overlay", lua::wrap}, + {"get_block_inventory", lua::wrap}, + {"close", lua::wrap}, + {"pause", lua::wrap}, + {"resume", lua::wrap}, + {"get_player", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index 5e9413ea..33cb0898 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -1,8 +1,4 @@ #include "api_lua.hpp" -#include "lua_util.hpp" -#include "lua_commons.hpp" -#include "LuaState.hpp" -#include "../scripting.hpp" #include "../../../window/input.hpp" #include "../../../window/Events.hpp" @@ -13,7 +9,6 @@ #include "../../../engine.hpp" namespace scripting { - extern lua::LuaState* state; extern Hud* hud; } using namespace scripting; @@ -37,7 +32,7 @@ static int l_add_callback(lua_State* L) { throw std::runtime_error("unknown binding "+util::quote(bindname)); } lua_pushvalue(L, 2); - runnable actual_callback = state->createRunnable(L); + runnable actual_callback = lua::create_runnable(L); runnable callback = [=]() { if (!scripting::engine->getGUI()->isFocusCaught()) { actual_callback(); @@ -69,11 +64,11 @@ static int l_get_bindings(lua_State* L) { } const luaL_Reg inputlib [] = { - {"keycode", lua_wrap_errors}, - {"mousecode", lua_wrap_errors}, - {"add_callback", lua_wrap_errors}, - {"get_mouse_pos", lua_wrap_errors}, - {"get_bindings", lua_wrap_errors}, + {"keycode", lua::wrap}, + {"mousecode", lua::wrap}, + {"add_callback", lua::wrap}, + {"get_mouse_pos", lua::wrap}, + {"get_bindings", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libinventory.cpp b/src/logic/scripting/lua/libinventory.cpp index f6d164e1..362e2449 100644 --- a/src/logic/scripting/lua/libinventory.cpp +++ b/src/logic/scripting/lua/libinventory.cpp @@ -1,23 +1,21 @@ -#include "lua_commons.hpp" - #include "api_lua.hpp" -#include "lua_util.hpp" -#include "../scripting.hpp" #include "../../../content/Content.hpp" #include "../../../world/Level.hpp" #include "../../../items/ItemStack.hpp" #include "../../../items/Inventories.hpp" #include "../../../logic/BlocksController.hpp" +using namespace scripting; + static void validate_itemid(itemid_t id) { - if (id >= scripting::indices->countItemDefs()) { + if (id >= indices->countItemDefs()) { throw std::runtime_error("invalid item id"); } } static std::shared_ptr get_inventory(int64_t id) { - auto inv = scripting::level->inventories->get(id); + auto inv = level->inventories->get(id); if (inv == nullptr) { throw std::runtime_error("inventory not found: "+std::to_string(id)); } @@ -25,7 +23,7 @@ static std::shared_ptr get_inventory(int64_t id) { } static std::shared_ptr get_inventory(int64_t id, int arg) { - auto inv = scripting::level->inventories->get(id); + auto inv = level->inventories->get(id); if (inv == nullptr) { throw std::runtime_error("inventory not found: "+std::to_string(id)+ " argument "+std::to_string(arg)); @@ -40,21 +38,21 @@ static void validate_slotid(int slotid, Inventory* inv) { } static int l_inventory_get(lua_State* L) { - lua_Integer invid = lua_tointeger(L, 1); - lua_Integer slotid = lua_tointeger(L, 2); + auto invid = lua::tointeger(L, 1); + auto slotid = lua::tointeger(L, 2); auto inv = get_inventory(invid); validate_slotid(slotid, inv.get()); const ItemStack& item = inv->getSlot(slotid); - lua_pushinteger(L, item.getItemId()); - lua_pushinteger(L, item.getCount()); + lua::pushinteger(L, item.getItemId()); + lua::pushinteger(L, item.getCount()); return 2; } static int l_inventory_set(lua_State* L) { - lua_Integer invid = lua_tointeger(L, 1); - lua_Integer slotid = lua_tointeger(L, 2); - lua_Integer itemid = lua_tointeger(L, 3); - lua_Integer count = lua_tointeger(L, 4); + auto invid = lua::tointeger(L, 1); + auto slotid = lua::tointeger(L, 2); + auto itemid = lua::tointeger(L, 3); + auto count = lua::tointeger(L, 4); validate_itemid(itemid); auto inv = get_inventory(invid); @@ -66,90 +64,85 @@ static int l_inventory_set(lua_State* L) { } static int l_inventory_size(lua_State* L) { - lua_Integer invid = lua_tointeger(L, 1); + auto invid = lua::tointeger(L, 1); auto inv = get_inventory(invid); - lua_pushinteger(L, inv->size()); - return 1; + return lua::pushinteger(L, inv->size()); } static int l_inventory_add(lua_State* L) { - lua_Integer invid = lua_tointeger(L, 1); - lua_Integer itemid = lua_tointeger(L, 2); - lua_Integer count = lua_tointeger(L, 3); + auto invid = lua::tointeger(L, 1); + auto itemid = lua::tointeger(L, 2); + auto count = lua::tointeger(L, 3); validate_itemid(itemid); auto inv = get_inventory(invid); ItemStack item(itemid, count); - inv->move(item, scripting::indices); - lua_pushinteger(L, item.getCount()); - return 1; + inv->move(item, indices); + return lua::pushinteger(L, item.getCount()); } static int l_inventory_get_block(lua_State* L) { - lua_Integer x = lua_tointeger(L, 1); - lua_Integer y = lua_tointeger(L, 2); - lua_Integer z = lua_tointeger(L, 3); - int64_t id = scripting::blocks->createBlockInventory(x, y, z); - lua_pushinteger(L, id); - return 1; + auto x = lua::tointeger(L, 1); + auto y = lua::tointeger(L, 2); + auto z = lua::tointeger(L, 3); + int64_t id = blocks->createBlockInventory(x, y, z); + return lua::pushinteger(L, id); } static int l_inventory_bind_block(lua_State* L) { - lua_Integer id = lua_tointeger(L, 1); - lua_Integer x = lua_tointeger(L, 2); - lua_Integer y = lua_tointeger(L, 3); - lua_Integer z = lua_tointeger(L, 4); - scripting::blocks->bindInventory(id, x, y, z); + auto id = lua::tointeger(L, 1); + auto x = lua::tointeger(L, 2); + auto y = lua::tointeger(L, 3); + auto z = lua::tointeger(L, 4); + blocks->bindInventory(id, x, y, z); return 0; } static int l_inventory_unbind_block(lua_State* L) { - lua_Integer x = lua_tointeger(L, 1); - lua_Integer y = lua_tointeger(L, 2); - lua_Integer z = lua_tointeger(L, 3); - scripting::blocks->unbindInventory(x, y, z); + auto x = lua::tointeger(L, 1); + auto y = lua::tointeger(L, 2); + auto z = lua::tointeger(L, 3); + blocks->unbindInventory(x, y, z); return 0; } static int l_inventory_clone(lua_State* L) { - lua_Integer id = lua_tointeger(L, 1); - auto clone = scripting::level->inventories->clone(id); + auto id = lua::tointeger(L, 1); + auto clone = level->inventories->clone(id); if (clone == nullptr) { - lua_pushinteger(L, 0); - return 1; + return lua::pushinteger(L, 0); } - lua_pushinteger(L, clone->getId()); - return 1; + return lua::pushinteger(L, clone->getId()); } static int l_inventory_move(lua_State* L) { - lua_Integer invAid = lua_tointeger(L, 1); - lua_Integer slotAid = lua_tointeger(L, 2); + auto invAid = lua::tointeger(L, 1); + auto slotAid = lua::tointeger(L, 2); auto invA = get_inventory(invAid, 1); validate_slotid(slotAid, invA.get()); - lua_Integer invBid = lua_tointeger(L, 3); - lua_Integer slotBid = lua_isnil(L, 4) ? -1 : lua_tointeger(L, 4); + auto invBid = lua::tointeger(L, 3); + auto slotBid = lua_isnil(L, 4) ? -1 : lua::tointeger(L, 4); auto invB = get_inventory(invBid, 3); auto& slot = invA->getSlot(slotAid); if (slotBid == -1) { - invB->move(slot, scripting::content->getIndices()); + invB->move(slot, content->getIndices()); } else { - invB->move(slot, scripting::content->getIndices(), slotBid, slotBid+1); + invB->move(slot, content->getIndices(), slotBid, slotBid+1); } return 0; } const luaL_Reg inventorylib [] = { - {"get", lua_wrap_errors}, - {"set", lua_wrap_errors}, - {"size", lua_wrap_errors}, - {"add", lua_wrap_errors}, - {"move", lua_wrap_errors}, - {"get_block", lua_wrap_errors}, - {"bind_block", lua_wrap_errors}, - {"unbind_block", lua_wrap_errors}, - {"clone", lua_wrap_errors}, + {"get", lua::wrap}, + {"set", lua::wrap}, + {"size", lua::wrap}, + {"add", lua::wrap}, + {"move", lua::wrap}, + {"get_block", lua::wrap}, + {"bind_block", lua::wrap}, + {"unbind_block", lua::wrap}, + {"clone", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libitem.cpp b/src/logic/scripting/lua/libitem.cpp index 16d8d877..162a9c09 100644 --- a/src/logic/scripting/lua/libitem.cpp +++ b/src/logic/scripting/lua/libitem.cpp @@ -1,53 +1,43 @@ -#include "lua_commons.hpp" -#include "lua_util.hpp" #include "api_lua.hpp" -#include "LuaState.hpp" -#include "../scripting.hpp" + #include "../../../content/Content.hpp" #include "../../../items/ItemDef.hpp" -namespace scripting { - extern lua::LuaState* state; -} using namespace scripting; static int l_item_name(lua_State* L) { auto indices = content->getIndices(); - auto id = lua_tointeger(L, 1); + auto id = lua::tointeger(L, 1); if (static_cast(id) >= indices->countItemDefs()) { return 0; } auto def = indices->getItemDef(id); - lua_pushstring(L, def->name.c_str()); - return 1; + return lua::pushstring(L, def->name); } static int l_item_index(lua_State* L) { auto name = lua::require_string(L, 1); - lua_pushinteger(L, content->requireItem(name).rt.id); - return 1; + return lua::pushinteger(L, content->requireItem(name).rt.id); } static int l_item_stack_size(lua_State* L) { auto indices = content->getIndices(); - auto id = lua_tointeger(L, 1); + auto id = lua::tointeger(L, 1); if (static_cast(id) >= indices->countItemDefs()) { return 0; } auto def = indices->getItemDef(id); - lua_pushinteger(L, def->stackSize); - return 1; + return lua::pushinteger(L, def->stackSize); } static int l_item_defs_count(lua_State* L) { - lua_pushinteger(L, scripting::indices->countItemDefs()); - return 1; + return lua::pushinteger(L, indices->countItemDefs()); } const luaL_Reg itemlib [] = { - {"index", lua_wrap_errors}, - {"name", lua_wrap_errors}, - {"stack_size", lua_wrap_errors}, - {"defs_count", lua_wrap_errors}, + {"index", lua::wrap}, + {"name", lua::wrap}, + {"stack_size", lua::wrap}, + {"defs_count", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libjson.cpp b/src/logic/scripting/lua/libjson.cpp index 9cb316b4..2a9508e6 100644 --- a/src/logic/scripting/lua/libjson.cpp +++ b/src/logic/scripting/lua/libjson.cpp @@ -1,23 +1,15 @@ #include "api_lua.hpp" -#include "lua_util.hpp" -#include "lua_commons.hpp" -#include "LuaState.hpp" #include "../../../coders/json.hpp" #include "../../../data/dynamic.hpp" -namespace scripting { - extern lua::LuaState* state; -} - static int l_json_stringify(lua_State* L) { auto value = lua::tovalue(L, 1); if (auto mapptr = std::get_if(&value)) { - bool nice = lua_toboolean(L, 2); + bool nice = lua::toboolean(L, 2); auto string = json::stringify(mapptr->get(), nice, " "); - lua_pushstring(L, string.c_str()); - return 1; + return lua::pushstring(L, string.c_str()); } else { throw std::runtime_error("table expected"); } @@ -26,12 +18,11 @@ static int l_json_stringify(lua_State* L) { static int l_json_parse(lua_State* L) { auto string = lua::require_string(L, 1); auto element = json::parse("", string); - lua::pushvalue(L, element); - return 1; + return lua::pushvalue(L, element); } const luaL_Reg jsonlib [] = { - {"tostring", lua_wrap_errors}, - {"parse", lua_wrap_errors}, + {"tostring", lua::wrap}, + {"parse", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libpack.cpp b/src/logic/scripting/lua/libpack.cpp index 683f17e3..931823ac 100644 --- a/src/logic/scripting/lua/libpack.cpp +++ b/src/logic/scripting/lua/libpack.cpp @@ -1,7 +1,5 @@ #include "api_lua.hpp" -#include "lua_commons.hpp" -#include "../scripting.hpp" #include "../../../engine.hpp" #include "../../../assets/AssetsLoader.hpp" #include "../../../files/engine_paths.hpp" @@ -14,29 +12,28 @@ #include #include +using namespace scripting; + static int l_pack_get_folder(lua_State* L) { - std::string packName = lua_tostring(L, 1); + std::string packName = lua::tostring(L, 1); if (packName == "core") { - auto folder = scripting::engine->getPaths()->getResources().u8string()+"/"; - lua_pushstring(L, folder.c_str()); - return 1; + auto folder = engine->getPaths()->getResources().u8string()+"/"; + return lua::pushstring(L, folder); } - for (auto& pack : scripting::engine->getContentPacks()) { + for (auto& pack : engine->getContentPacks()) { if (pack.id == packName) { - lua_pushstring(L, (pack.folder.u8string()+"/").c_str()); - return 1; + return lua::pushstring(L, pack.folder.u8string()+"/"); } } - lua_pushstring(L, ""); - return 1; + return lua::pushstring(L, ""); } /// @brief pack.get_installed() -> array static int l_pack_get_installed(lua_State* L) { - auto& packs = scripting::engine->getContentPacks(); + auto& packs = engine->getContentPacks(); lua_createtable(L, packs.size(), 0); for (size_t i = 0; i < packs.size(); i++) { - lua_pushstring(L, packs[i].id.c_str()); + lua::pushstring(L, packs[i].id); lua_rawseti(L, -2, i + 1); } return 1; @@ -45,13 +42,13 @@ static int l_pack_get_installed(lua_State* L) { /// @brief pack.get_available() -> array static int l_pack_get_available(lua_State* L) { fs::path worldFolder(""); - if (scripting::level) { - worldFolder = scripting::level->getWorld()->wfile->getFolder(); + if (level) { + worldFolder = level->getWorld()->wfile->getFolder(); } - auto manager = scripting::engine->createPacksManager(worldFolder); + auto manager = engine->createPacksManager(worldFolder); manager.scan(); - const auto& installed = scripting::engine->getContentPacks(); + const auto& installed = engine->getContentPacks(); for (auto& pack : installed) { manager.exclude(pack.id); } @@ -59,7 +56,7 @@ static int l_pack_get_available(lua_State* L) { lua_createtable(L, names.size(), 0); for (size_t i = 0; i < names.size(); i++) { - lua_pushstring(L, names[i].c_str()); + lua::pushstring(L, names[i]); lua_rawseti(L, -2, i + 1); } return 1; @@ -68,22 +65,22 @@ static int l_pack_get_available(lua_State* L) { static int l_pack_get_info(lua_State* L, const ContentPack& pack, const Content* content) { lua_createtable(L, 0, 5); - lua_pushstring(L, pack.id.c_str()); - lua_setfield(L, -2, "id"); + lua::pushstring(L, pack.id); + lua::setfield(L, "id"); - lua_pushstring(L, pack.title.c_str()); - lua_setfield(L, -2, "title"); + lua::pushstring(L, pack.title); + lua::setfield(L, "title"); - lua_pushstring(L, pack.creator.c_str()); - lua_setfield(L, -2, "creator"); + lua::pushstring(L, pack.creator); + lua::setfield(L, "creator"); - lua_pushstring(L, pack.description.c_str()); - lua_setfield(L, -2, "description"); + lua::pushstring(L, pack.description); + lua::setfield(L, "description"); - lua_pushstring(L, pack.version.c_str()); - lua_setfield(L, -2, "version"); + lua::pushstring(L, pack.version); + lua::setfield(L, "version"); - auto assets = scripting::engine->getAssets(); + auto assets = engine->getAssets(); std::string icon = pack.id+".icon"; if (!AssetsLoader::loadExternalTexture(assets, icon, { pack.folder/fs::path("icon.png") @@ -91,8 +88,8 @@ static int l_pack_get_info(lua_State* L, const ContentPack& pack, const Content* icon = "gui/no_icon"; } - lua_pushstring(L, icon.c_str()); - lua_setfield(L, -2, "icon"); + lua::pushstring(L, icon); + lua::setfield(L, "icon"); if (!pack.dependencies.empty()) { lua_createtable(L, pack.dependencies.size(), 0); @@ -108,13 +105,13 @@ static int l_pack_get_info(lua_State* L, const ContentPack& pack, const Content* lua_pushfstring(L, "%s%s", prefix.c_str(), dpack.id.c_str()); lua_rawseti(L, -2, i+1); } - lua_setfield(L, -2, "dependencies"); + lua::setfield(L, "dependencies"); } auto runtime = content ? content->getPackRuntime(pack.id) : nullptr; if (runtime) { - lua_pushboolean(L, runtime->getStats().hasSavingContent()); - lua_setfield(L, -2, "has_indices"); + lua::pushboolean(L, runtime->getStats().hasSavingContent()); + lua::setfield(L, "has_indices"); } return 1; } @@ -163,10 +160,10 @@ static int l_pack_get_base_packs(lua_State* L) { } const luaL_Reg packlib [] = { - {"get_folder", lua_wrap_errors}, - {"get_installed", lua_wrap_errors}, - {"get_available", lua_wrap_errors}, - {"get_info", lua_wrap_errors}, - {"get_base_packs", lua_wrap_errors}, + {"get_folder", lua::wrap}, + {"get_installed", lua::wrap}, + {"get_available", lua::wrap}, + {"get_info", lua::wrap}, + {"get_base_packs", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index fde82362..6db20c60 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -1,6 +1,5 @@ -#include "lua_commons.hpp" #include "api_lua.hpp" -#include "../scripting.hpp" + #include "../../../world/Level.hpp" #include "../../../objects/Player.hpp" #include "../../../physics/Hitbox.hpp" @@ -9,20 +8,17 @@ #include +using namespace scripting; + inline std::shared_ptr get_player(lua_State* L, int idx) { - return scripting::level->getObject(lua_tointeger(L, idx)); + return level->getObject(lua::tointeger(L, idx)); } static int l_player_get_pos(lua_State* L) { - auto player = get_player(L, 1); - if (!player) { - return 0; + if (auto player = get_player(L, 1)) { + return lua::pushvec3(L, player->hitbox->position); } - glm::vec3 pos = player->hitbox->position; - lua_pushnumber(L, pos.x); - lua_pushnumber(L, pos.y); - lua_pushnumber(L, pos.z); - return 3; + return 0; } static int l_player_set_pos(lua_State* L) { @@ -30,23 +26,18 @@ static int l_player_set_pos(lua_State* L) { if (!player) { return 0; } - auto x = lua_tonumber(L, 2); - auto y = lua_tonumber(L, 3); - auto z = lua_tonumber(L, 4); + auto x = lua::tonumber(L, 2); + auto y = lua::tonumber(L, 3); + auto z = lua::tonumber(L, 4); player->hitbox->position = glm::vec3(x, y, z); return 0; } static int l_player_get_vel(lua_State* L) { - auto player = get_player(L, 1); - if (!player) { - return 0; + if (auto player = get_player(L, 1)) { + return lua::pushvec3(L, player->hitbox->velocity); } - glm::vec3 vel = player->hitbox->velocity; - lua_pushnumber(L, vel.x); - lua_pushnumber(L, vel.y); - lua_pushnumber(L, vel.z); - return 3; + return 0; } static int l_player_set_vel(lua_State* L) { @@ -54,23 +45,18 @@ static int l_player_set_vel(lua_State* L) { if (!player) { return 0; } - auto x = lua_tonumber(L, 2); - auto y = lua_tonumber(L, 3); - auto z = lua_tonumber(L, 4); + auto x = lua::tonumber(L, 2); + auto y = lua::tonumber(L, 3); + auto z = lua::tonumber(L, 4); player->hitbox->velocity = glm::vec3(x, y, z); return 0; } static int l_player_get_rot(lua_State* L) { - auto player = get_player(L, 1); - if (!player) { - return 0; + if (auto player = get_player(L, 1)) { + return lua::pushvec3(L, player->cam); } - const glm::vec3& rot = player->cam; - lua_pushnumber(L, rot.x); - lua_pushnumber(L, rot.y); - lua_pushnumber(L, rot.z); - return 3; + return 0; } static int l_player_set_rot(lua_State* L) { @@ -80,11 +66,11 @@ static int l_player_set_rot(lua_State* L) { } glm::vec3& cam = player->cam; - lua_Number x = lua_tonumber(L, 2); - lua_Number y = lua_tonumber(L, 3); + lua_Number x = lua::tonumber(L, 2); + lua_Number y = lua::tonumber(L, 3); lua_Number z = cam.z; if (lua_isnumber(L, 4)) { - z = lua_tonumber(L, 4); + z = lua::tonumber(L, 4); } cam.x = x; cam.y = y; @@ -97,37 +83,35 @@ static int l_player_get_inv(lua_State* L) { if (!player) { return 0; } - lua_pushinteger(L, player->getInventory()->getId()); - lua_pushinteger(L, player->getChosenSlot()); + lua::pushinteger(L, player->getInventory()->getId()); + lua::pushinteger(L, player->getChosenSlot()); return 2; } static int l_player_is_flight(lua_State* L) { if (auto player = get_player(L, 1)) { - lua_pushboolean(L, player->isFlight()); - return 1; + return lua::pushboolean(L, player->isFlight()); } return 0; } static int l_player_set_flight(lua_State* L) { if (auto player = get_player(L, 1)) { - player->setFlight(lua_toboolean(L, 2)); + player->setFlight(lua::toboolean(L, 2)); } return 0; } static int l_player_is_noclip(lua_State* L) { if (auto player = get_player(L, 1)) { - lua_pushboolean(L, player->isNoclip()); - return 1; + return lua::pushboolean(L, player->isNoclip()); } return 0; } static int l_player_set_noclip(lua_State* L) { if (auto player = get_player(L, 1)) { - player->setNoclip(lua_toboolean(L, 2)); + player->setNoclip(lua::toboolean(L, 2)); } return 0; } @@ -137,27 +121,23 @@ static int l_player_get_selected_block(lua_State* L) { if (player->selection.vox.id == BLOCK_VOID) { return 0; } - const glm::ivec3 pos = player->selection.position; - lua_pushinteger(L, pos.x); - lua_pushinteger(L, pos.y); - lua_pushinteger(L, pos.z); - return 3; + return lua::pushivec3(L, player->selection.position); } return 0; } const luaL_Reg playerlib [] = { - {"get_pos", lua_wrap_errors}, - {"set_pos", lua_wrap_errors}, - {"get_vel", lua_wrap_errors}, - {"set_vel", lua_wrap_errors}, - {"get_rot", lua_wrap_errors}, - {"set_rot", lua_wrap_errors}, - {"get_inventory", lua_wrap_errors}, - {"is_flight", lua_wrap_errors}, - {"set_flight", lua_wrap_errors}, - {"is_noclip", lua_wrap_errors}, - {"set_noclip", lua_wrap_errors}, - {"get_selected_block", lua_wrap_errors}, + {"get_pos", lua::wrap}, + {"set_pos", lua::wrap}, + {"get_vel", lua::wrap}, + {"set_vel", lua::wrap}, + {"get_rot", lua::wrap}, + {"set_rot", lua::wrap}, + {"get_inventory", lua::wrap}, + {"is_flight", lua::wrap}, + {"set_flight", lua::wrap}, + {"is_noclip", lua::wrap}, + {"set_noclip", lua::wrap}, + {"get_selected_block", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libtime.cpp b/src/logic/scripting/lua/libtime.cpp index b5a19a0a..392a387f 100644 --- a/src/logic/scripting/lua/libtime.cpp +++ b/src/logic/scripting/lua/libtime.cpp @@ -1,21 +1,18 @@ #include "api_lua.hpp" -#include "lua_commons.hpp" -#include "../scripting.hpp" + #include "../../../engine.hpp" #include "../../../window/Window.hpp" static int l_time_uptime(lua_State* L) { - lua_pushnumber(L, Window::time()); - return 1; + return lua::pushnumber(L, Window::time()); } static int l_time_delta(lua_State* L) { - lua_pushnumber(L, scripting::engine->getDelta()); - return 1; + return lua::pushnumber(L, scripting::engine->getDelta()); } const luaL_Reg timelib [] = { - {"uptime", lua_wrap_errors}, - {"delta", lua_wrap_errors}, + {"uptime", lua::wrap}, + {"delta", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libtoml.cpp b/src/logic/scripting/lua/libtoml.cpp index 29348eeb..5d5bb9dd 100644 --- a/src/logic/scripting/lua/libtoml.cpp +++ b/src/logic/scripting/lua/libtoml.cpp @@ -1,14 +1,8 @@ #include "api_lua.hpp" -#include "lua_util.hpp" -#include "lua_commons.hpp" -#include "LuaState.hpp" #include "../../../coders/toml.hpp" #include "../../../data/dynamic.hpp" -namespace scripting { - extern lua::LuaState* state; -} using namespace scripting; static int l_toml_stringify(lua_State* L) { @@ -16,8 +10,7 @@ static int l_toml_stringify(lua_State* L) { if (auto mapptr = std::get_if(&value)) { auto string = toml::stringify(**mapptr); - lua_pushstring(L, string.c_str()); - return 1; + return lua::pushstring(L, string); } else { throw std::runtime_error("table expected"); } @@ -27,12 +20,11 @@ static int l_toml_parse(lua_State* L) { auto string = lua::require_string(L, 1); auto element = toml::parse("", string); auto value = std::make_unique(element); - lua::pushvalue(L, *value); - return 1; + return lua::pushvalue(L, *value); } const luaL_Reg tomllib [] = { - {"tostring", lua_wrap_errors}, - {"parse", lua_wrap_errors}, + {"tostring", lua::wrap}, + {"parse", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libworld.cpp b/src/logic/scripting/lua/libworld.cpp index 51ec7e0e..13eddb7a 100644 --- a/src/logic/scripting/lua/libworld.cpp +++ b/src/logic/scripting/lua/libworld.cpp @@ -1,7 +1,5 @@ -#include "lua_commons.hpp" #include "api_lua.hpp" -#include "../scripting.hpp" #include "../../../assets/Assets.hpp" #include "../../../assets/AssetsLoader.hpp" #include "../../../files/engine_paths.hpp" @@ -12,10 +10,11 @@ #include #include +using namespace scripting; namespace fs = std::filesystem; static int l_world_get_list(lua_State* L) { - auto paths = scripting::engine->getPaths(); + auto paths = engine->getPaths(); auto worlds = paths->scanForWorlds(); lua_createtable(L, worlds.size(), 0); @@ -23,10 +22,10 @@ static int l_world_get_list(lua_State* L) { lua_createtable(L, 0, 1); auto name = worlds[i].filename().u8string(); - lua_pushstring(L, name.c_str()); - lua_setfield(L, -2, "name"); + lua::pushstring(L, name); + lua::setfield(L, "name"); - auto assets = scripting::engine->getAssets(); + auto assets = engine->getAssets(); std::string icon = "world:"+name+".icon"; if (!AssetsLoader::loadExternalTexture(assets, icon, { worlds[i]/fs::path("icon.png"), @@ -34,8 +33,8 @@ static int l_world_get_list(lua_State* L) { })) { icon = "gui/no_world_icon"; } - lua_pushstring(L, icon.c_str()); - lua_setfield(L, -2, "icon"); + lua::pushstring(L, icon); + lua::setfield(L, "icon"); lua_rawseti(L, -2, i + 1); } @@ -43,39 +42,35 @@ static int l_world_get_list(lua_State* L) { } static int l_world_get_total_time(lua_State* L) { - lua_pushnumber(L, scripting::level->getWorld()->totalTime); - return 1; + return lua::pushnumber(L, level->getWorld()->totalTime); } static int l_world_get_day_time(lua_State* L) { - lua_pushnumber(L, scripting::level->getWorld()->daytime); - return 1; + return lua::pushnumber(L, level->getWorld()->daytime); } static int l_world_set_day_time(lua_State* L) { - double value = lua_tonumber(L, 1); - scripting::level->getWorld()->daytime = fmod(value, 1.0); + auto value = lua::tonumber(L, 1); + level->getWorld()->daytime = fmod(value, 1.0); return 0; } static int l_world_get_seed(lua_State* L) { - lua_pushinteger(L, scripting::level->getWorld()->getSeed()); - return 1; + return lua::pushinteger(L, level->getWorld()->getSeed()); } static int l_world_exists(lua_State* L) { - auto name = lua_tostring(L, 1); - auto worldsDir = scripting::engine->getPaths()->getWorldFolder(name); - lua_pushboolean(L, fs::is_directory(worldsDir)); - return 1; + auto name = lua::require_string(L, 1); + auto worldsDir = engine->getPaths()->getWorldFolder(name); + return lua::pushboolean(L, fs::is_directory(worldsDir)); } const luaL_Reg worldlib [] = { - {"get_list", lua_wrap_errors}, - {"get_total_time", lua_wrap_errors}, - {"get_day_time", lua_wrap_errors}, - {"set_day_time", lua_wrap_errors}, - {"get_seed", lua_wrap_errors}, - {"exists", lua_wrap_errors}, + {"get_list", lua::wrap}, + {"get_total_time", lua::wrap}, + {"get_day_time", lua::wrap}, + {"set_day_time", lua::wrap}, + {"get_seed", lua::wrap}, + {"exists", lua::wrap}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_commons.cpp b/src/logic/scripting/lua/lua_commons.cpp new file mode 100644 index 00000000..00669d03 --- /dev/null +++ b/src/logic/scripting/lua/lua_commons.cpp @@ -0,0 +1,9 @@ +#include "lua_commons.hpp" + +#include "../../../debug/Logger.hpp" + +static debug::Logger logger("lua"); + +void lua::log_error(const std::string& text) { + logger.error() << text; +} diff --git a/src/logic/scripting/lua/lua_commons.hpp b/src/logic/scripting/lua/lua_commons.hpp index f51b7aac..e1e4dddb 100644 --- a/src/logic/scripting/lua/lua_commons.hpp +++ b/src/logic/scripting/lua/lua_commons.hpp @@ -1,34 +1,31 @@ #ifndef LOGIC_SCRIPTING_LUA_HPP_ #define LOGIC_SCRIPTING_LUA_HPP_ +#include "../../../delegates.hpp" +#include "../scripting.hpp" + #ifdef __linux__ #include #include #else #include #endif +#include + +#include +#include #ifndef LUAJIT_VERSION #error LuaJIT required #endif -#include -#include +namespace lua { + class luaerror : public std::runtime_error { + public: + luaerror(const std::string& message); + }; -template int lua_wrap_errors(lua_State *L) { - int result = 0; - try { - result = func(L); - } - // transform exception with description into lua_error - catch (std::exception &e) { - luaL_error(L, e.what()); - } - // Rethrow any other exception (lua error for example) - catch (...) { - throw; - } - return result; + void log_error(const std::string& text); } #endif // LOGIC_SCRIPTING_LUA_HPP_ diff --git a/src/logic/scripting/lua/lua_util.cpp b/src/logic/scripting/lua/lua_util.cpp index 24cee222..02a4dce3 100644 --- a/src/logic/scripting/lua/lua_util.cpp +++ b/src/logic/scripting/lua/lua_util.cpp @@ -1,9 +1,17 @@ #include "lua_util.hpp" -#include "../../../debug/Logger.hpp" #include "../../../util/stringutil.hpp" -static debug::Logger logger("lua"); +#include +#include + +using namespace lua; + +static int nextEnvironment = 1; + +std::string lua::env_name(int env) { + return "_ENV"+util::mangleid(env); +} int lua::pushvalue(lua_State* L, const dynamic::Value& value) { using namespace dynamic; @@ -97,10 +105,6 @@ dynamic::Value lua::tovalue(lua_State* L, int idx) { } } -void lua::logError(const std::string& text) { - logger.error() << text; -} - int lua::call(lua_State* L, int argc, int nresults) { if (lua_pcall(L, argc, nresults, 0)) { throw luaerror(lua_tostring(L, -1)); @@ -108,10 +112,110 @@ int lua::call(lua_State* L, int argc, int nresults) { return 1; } -int lua::callNoThrow(lua_State* L, int argc) { +int lua::call_nothrow(lua_State* L, int argc) { if (lua_pcall(L, argc, LUA_MULTRET, 0)) { - logError(lua_tostring(L, -1)); + log_error(lua_tostring(L, -1)); return 0; } return 1; } + +void lua::dump_stack(lua_State* L) { + int top = lua_gettop(L); + for (int i = 1; i <= top; i++) { + std::cout << std::setw(3) << i << std::setw(20) << luaL_typename(L, i) << std::setw(30); + switch (lua_type(L, i)) { + case LUA_TNUMBER: + std::cout << lua_tonumber(L, i); + break; + case LUA_TSTRING: + std::cout << lua_tostring(L, i); + break; + case LUA_TBOOLEAN: + std::cout << (lua_toboolean(L, i) ? "true" : "false"); + break; + case LUA_TNIL: + std::cout << "nil"; + break; + default: + std::cout << lua_topointer(L, i); + break; + } + std::cout << std::endl; + } +} + +static std::shared_ptr createLambdaHandler(lua_State* L) { + auto ptr = reinterpret_cast(lua_topointer(L, -1)); + auto name = util::mangleid(ptr); + getglobal(L, LAMBDAS_TABLE); + pushvalue(L, -2); + setfield(L, name); + pop(L, 2); + + return std::shared_ptr(new std::string(name), [=](std::string* name) { + getglobal(L, LAMBDAS_TABLE); + pushnil(L); + setfield(L, *name); + pop(L); + delete name; + }); +} + +runnable lua::create_runnable(lua_State* L) { + auto funcptr = createLambdaHandler(L); + return [=]() { + lua_getglobal(L, LAMBDAS_TABLE.c_str()); + lua_getfield(L, -1, funcptr->c_str()); + call_nothrow(L, 0); + }; +} + +scripting::common_func lua::create_lambda(lua_State* L) { + auto funcptr = createLambdaHandler(L); + return [=](const std::vector& args) { + lua_getglobal(L, LAMBDAS_TABLE.c_str()); + lua_getfield(L, -1, funcptr->c_str()); + for (const auto& arg : args) { + pushvalue(L, arg); + } + if (call(L, args.size(), 1)) { + auto result = tovalue(L, -1); + lua_pop(L, 1); + return result; + } + return dynamic::Value(dynamic::NONE); + }; +} + +int lua::createEnvironment(lua_State* L, int parent) { + int id = nextEnvironment++; + + // local env = {} + lua_createtable(L, 0, 1); + + // setmetatable(env, {__index=_G}) + lua_createtable(L, 0, 1); + if (parent == 0) { + pushglobals(L); + } else { + if (pushenv(L, parent) == 0) { + pushglobals(L); + } + } + setfield(L, "__index"); + lua_setmetatable(L, -2); + + // envname = env + setglobal(L, env_name(id)); + return id; +} + + +void lua::removeEnvironment(lua_State* L, int id) { + if (id == 0) { + return; + } + pushnil(L); + setglobal(L, env_name(id)); +} diff --git a/src/logic/scripting/lua/lua_util.hpp b/src/logic/scripting/lua/lua_util.hpp index e9833c79..dd4d7034 100644 --- a/src/logic/scripting/lua/lua_util.hpp +++ b/src/logic/scripting/lua/lua_util.hpp @@ -1,19 +1,33 @@ #ifndef LOGIC_SCRIPTING_LUA_UTIL_HPP_ #define LOGIC_SCRIPTING_LUA_UTIL_HPP_ -#include "LuaState.hpp" - -#ifdef __linux__ -#include -#include -#else -#include -#endif -#include - -#include +#include "lua_commons.hpp" namespace lua { + inline std::string LAMBDAS_TABLE = "$L"; + + std::string env_name(int env); + + template int wrap(lua_State *L) { + int result = 0; + try { + result = func(L); + } + // transform exception with description into lua_error + catch (std::exception &e) { + luaL_error(L, e.what()); + } + // Rethrow any other exception (lua error for example) + catch (...) { + throw; + } + return result; + } + + inline void pop(lua_State* L, int n=1) { + lua_pop(L, n); + } + // function wrappers with number of pushed values as return value inline int pushnil(lua_State* L) { @@ -144,6 +158,18 @@ namespace lua { return lua_toboolean(L, idx); } + inline lua_Integer tointeger(lua_State* L, int idx) { + return lua_tointeger(L, idx); + } + + inline lua_Number tonumber(lua_State* L, int idx) { + return lua_tonumber(L, idx); + } + + inline const char* tostring(lua_State* L, int idx) { + return lua_tostring(L, idx); + } + inline glm::vec2 tovec2(lua_State* L, int idx) { lua_pushvalue(L, idx); if (!lua_istable(L, idx) || lua_objlen(L, idx) < 2) { @@ -153,42 +179,30 @@ namespace lua { lua_Number x = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); lua_Number y = lua_tonumber(L, -1); lua_pop(L, 1); - lua_pop(L, 1); + pop(L); return glm::vec2(x, y); } inline glm::vec4 tocolor(lua_State* L, int idx) { - lua_pushvalue(L, idx); + pushvalue(L, idx); if (!lua_istable(L, -1) || lua_objlen(L, idx) < 4) { throw std::runtime_error("RGBA array required"); } lua_rawgeti(L, -1, 1); - lua_Number r = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number r = tonumber(L, -1); pop(L); lua_rawgeti(L, -1, 2); - lua_Number g = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number g = tonumber(L, -1); pop(L); lua_rawgeti(L, -1, 3); - lua_Number b = lua_tonumber(L, -1); lua_pop(L, 1); + lua_Number b = tonumber(L, -1); pop(L); lua_rawgeti(L, -1, 4); - lua_Number a = lua_tonumber(L, -1); lua_pop(L, 1); - lua_pop(L, 1); + lua_Number a = tonumber(L, -1); pop(L); + pop(L); return glm::vec4(r/255, g/255, b/255, a/255); } - inline const char* require_string(lua_State* L, int idx) { - if (!lua_isstring(L, idx)) { - throw luaerror("string expected at "+std::to_string(idx)); - } - return lua_tostring(L, idx); - } - - std::wstring require_wstring(lua_State*, int idx); int pushvalue(lua_State*, const dynamic::Value& value); dynamic::Value tovalue(lua_State*, int idx); - inline void pop(lua_State* L, int n=1) { - lua_pop(L, n); - } - inline bool getfield(lua_State* L, const std::string& name, int idx=-1) { lua_getfield(L, idx, name.c_str()); if (lua_isnil(L, -1)) { @@ -204,8 +218,8 @@ namespace lua { inline bool getglobal(lua_State* L, const std::string& name) { lua_getglobal(L, name.c_str()); - if (lua_isnil(L, lua_gettop(L))) { - lua_pop(L, lua_gettop(L)); + if (lua_isnil(L, -1)) { + pop(L); return false; } return true; @@ -213,11 +227,11 @@ namespace lua { inline bool hasglobal(lua_State* L, const std::string& name) { lua_getglobal(L, name.c_str()); - if (lua_isnil(L, lua_gettop(L))) { - lua_pop(L, lua_gettop(L)); + if (lua_isnil(L, -1)) { + lua_pop(L, -1); return false; } - lua_pop(L, lua_gettop(L)); + pop(L); return true; } @@ -225,9 +239,70 @@ namespace lua { lua_setglobal(L, name.c_str()); } - void logError(const std::string& text); + inline const char* require_string(lua_State* L, int idx) { + if (!lua_isstring(L, idx)) { + throw luaerror("string expected at "+std::to_string(idx)); + } + return tostring(L, idx); + } + + std::wstring require_wstring(lua_State*, int idx); + + inline bool rename(lua_State* L, const std::string& from, const std::string& to) { + const char* src = from.c_str(); + lua_getglobal(L, src); + if (lua_isnil(L, lua_gettop(L))) { + lua_pop(L, lua_gettop(L)); + return false; + } + lua_setglobal(L, to.c_str()); + + // remove previous + lua_pushnil(L); + lua_setglobal(L, src); + return true; + } + + inline void remove(lua_State* L, const std::string& name) { + lua_pushnil(L); + lua_setglobal(L, name.c_str()); + } + + inline void loadbuffer(lua_State* L, int env, const std::string& src, const std::string& file) { + if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) { + throw luaerror(lua_tostring(L, -1)); + } + if (env && getglobal(L, env_name(env))) { + lua_setfenv(L, -2); + } + } + int call(lua_State*, int argc, int nresults=-1); - int callNoThrow(lua_State*, int argc); + int call_nothrow(lua_State*, int argc); + + inline int eval(lua_State* L, int env, const std::string& src, const std::string& file="") { + auto srcText = "return "+src; + loadbuffer(L, env, srcText, file); + return call(L, 0); + } + + inline int execute(lua_State* L, int env, const std::string& src, const std::string& file="") { + loadbuffer(L, env, src, file); + return call_nothrow(L, 0); + } + + runnable create_runnable(lua_State*); + scripting::common_func create_lambda(lua_State* ); + + inline int pushenv(lua_State* L, int env) { + if (getglobal(L, env_name(env))) { + return 1; + } + return 0; + } + int createEnvironment(lua_State*, int parent); + void removeEnvironment(lua_State*, int id); + void dump_stack(lua_State*); } #endif // LOGIC_SCRIPTING_LUA_UTIL_HPP_ diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 18185ac7..0de194db 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -43,7 +43,7 @@ static void load_script(const fs::path& name) { fs::path file = paths->getResources()/fs::path("scripts")/name; std::string src = files::read_string(file); - state->execute(state->getMainThread(), 0, src, file.u8string()); + lua::execute(state->getMainThread(), 0, src, file.u8string()); } void scripting::initialize(Engine* engine) { @@ -61,24 +61,24 @@ scriptenv scripting::get_root_environment() { scriptenv scripting::create_pack_environment(const ContentPack& pack) { auto L = state->getMainThread(); - int id = state->createEnvironment(L, 0); - state->pushenv(L, id); + int id = lua::createEnvironment(L, 0); + lua::pushenv(L, id); lua::pushvalue(L, -1); lua::setfield(L, "PACK_ENV"); lua::pushstring(L, pack.id); lua::setfield(L, "PACK_ID"); lua::pop(L); return std::shared_ptr(new int(id), [=](int* id) { - state->removeEnvironment(L, *id); + lua::removeEnvironment(L, *id); delete id; }); } scriptenv scripting::create_doc_environment(const scriptenv& parent, const std::string& name) { auto L = state->getMainThread(); - int id = state->createEnvironment(L, *parent); - state->pushenv(L, id); - lua_pushvalue(L, -1); + int id = lua::createEnvironment(L, *parent); + lua::pushenv(L, id); + lua::pushvalue(L, -1); lua::setfield(L, "DOC_ENV"); lua::pushstring(L, name); lua::setfield(L, "DOC_NAME"); @@ -86,7 +86,7 @@ scriptenv scripting::create_doc_environment(const scriptenv& parent, const std:: if (lua::getglobal(L, "Document")) { if (lua::getfield(L, "new")) { lua::pushstring(L, name); - if (lua::callNoThrow(L, 1)) { + if (lua::call_nothrow(L, 1)) { lua::setfield(L, "document", -3); } } @@ -94,7 +94,7 @@ scriptenv scripting::create_doc_environment(const scriptenv& parent, const std:: } lua::pop(L); return std::shared_ptr(new int(id), [=](int* id) { - state->removeEnvironment(L, *id); + lua::removeEnvironment(L, *id); delete id; }); } @@ -102,7 +102,7 @@ scriptenv scripting::create_doc_environment(const scriptenv& parent, const std:: void scripting::process_post_runnables() { auto L = state->getMainThread(); if (lua::getglobal(L, "__process_post_runnables")) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } } @@ -144,12 +144,12 @@ void scripting::on_world_quit() { for (auto& pack : scripting::engine->getContentPacks()) { lua::getfield(L, "unload"); lua::pushstring(L, pack.id); - lua::callNoThrow(L, 1); + lua::call_nothrow(L, 1); } lua::pop(L); if (lua::getglobal(L, "__scripts_cleanup")) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } scripting::level = nullptr; scripting::content = nullptr; @@ -263,7 +263,7 @@ void scripting::on_ui_close(UiDocument* layout, Inventory* inventory) { bool scripting::register_event(int env, const std::string& name, const std::string& id) { auto L = state->getMainThread(); - if (state->pushenv(L, env) == 0) { + if (lua::pushenv(L, env) == 0) { lua::pushglobals(L); } if (lua::getfield(L, name)) { @@ -272,7 +272,7 @@ bool scripting::register_event(int env, const std::string& name, const std::stri lua::getfield(L, "on"); lua::pushstring(L, id); lua::getfield(L, name, -4); - lua::callNoThrow(L, 2); + lua::call_nothrow(L, 2); lua::pop(L); // remove previous name @@ -287,7 +287,7 @@ void scripting::load_block_script(const scriptenv& senv, const std::string& pref int env = *senv; std::string src = files::read_string(file); logger.info() << "script (block) " << file.u8string(); - state->execute(state->getMainThread(), env, src, file.u8string()); + lua::execute(state->getMainThread(), env, src, file.u8string()); funcsset.init = register_event(env, "init", prefix+".init"); funcsset.update = register_event(env, "on_update", prefix+".update"); funcsset.randupdate = register_event(env, "on_random_update", prefix+".randupdate"); @@ -301,7 +301,7 @@ void scripting::load_item_script(const scriptenv& senv, const std::string& prefi int env = *senv; std::string src = files::read_string(file); logger.info() << "script (item) " << file.u8string(); - state->execute(state->getMainThread(), env, src, file.u8string()); + lua::execute(state->getMainThread(), env, src, file.u8string()); funcsset.init = register_event(env, "init", prefix+".init"); funcsset.on_use = register_event(env, "on_use", prefix+".use"); @@ -314,8 +314,7 @@ void scripting::load_world_script(const scriptenv& senv, const std::string& pref std::string src = files::read_string(file); logger.info() << "loading world script for " << prefix; - - state->execute(state->getMainThread(), env, src, file.u8string()); + lua::execute(state->getMainThread(), env, src, file.u8string()); register_event(env, "init", prefix+".init"); register_event(env, "on_world_open", prefix+".worldopen"); @@ -330,7 +329,7 @@ void scripting::load_layout_script(const scriptenv& senv, const std::string& pre std::string src = files::read_string(file); logger.info() << "loading script " << file.u8string(); - state->execute(state->getMainThread(), env, src, file.u8string()); + lua::execute(state->getMainThread(), env, src, file.u8string()); script.onopen = register_event(env, "on_open", prefix+".open"); script.onprogress = register_event(env, "on_progress", prefix+".progress"); script.onclose = register_event(env, "on_close", prefix+".close"); diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index c381dc35..6f9bad9c 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -8,11 +8,10 @@ namespace scripting { extern lua::LuaState* state; } +using namespace scripting; static debug::Logger logger("scripting_func"); -using namespace scripting; - runnable scripting::create_runnable( const scriptenv& env, const std::string& src, @@ -20,8 +19,8 @@ runnable scripting::create_runnable( ) { auto L = state->getMainThread(); try { - state->loadbuffer(L, *env, src, file); - return state->createRunnable(L); + lua::loadbuffer(L, *env, src, file); + return lua::create_runnable(L); } catch (const lua::luaerror& err) { logger.error() << err.what(); return [](){}; @@ -35,7 +34,7 @@ static lua_State* processCallback( ) { auto L = state->getMainThread(); try { - if (state->eval(L, *env, src, file) != 0) { + if (lua::eval(L, *env, src, file) != 0) { return L; } } catch (lua::luaerror& err) { @@ -52,7 +51,7 @@ wstringconsumer scripting::create_wstring_consumer( return [=](const std::wstring& x){ if (auto L = processCallback(env, src, file)) { lua::pushwstring(L, x); - lua::callNoThrow(L, 1); + lua::call_nothrow(L, 1); } }; } @@ -65,7 +64,7 @@ wstringsupplier scripting::create_wstring_supplier( return [=](){ if (auto L = processCallback(env, src, file)) { if (lua_isfunction(L, -1)) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } auto str = lua::require_wstring(L, -1); lua_pop(L, 1); return str; @@ -82,7 +81,7 @@ wstringchecker scripting::create_wstring_validator( return [=](const std::wstring& x){ if (auto L = processCallback(env, src, file)) { lua::pushwstring(L, x); - if (lua::callNoThrow(L, 1)) + if (lua::call_nothrow(L, 1)) return lua::toboolean(L, -1); } return false; @@ -97,7 +96,7 @@ boolconsumer scripting::create_bool_consumer( return [=](bool x){ if (auto L = processCallback(env, src, file)) { lua::pushboolean(L, x); - lua::callNoThrow(L, 1); + lua::call_nothrow(L, 1); } }; } @@ -110,7 +109,7 @@ boolsupplier scripting::create_bool_supplier( return [=](){ if (auto L = processCallback(env, src, file)) { if (lua_isfunction(L, -1)) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } bool x = lua::toboolean(L,-1); lua_pop(L, 1); return x; @@ -127,7 +126,7 @@ doubleconsumer scripting::create_number_consumer( return [=](double x){ if (auto L = processCallback(env, src, file)) { lua::pushnumber(L, x); - lua::callNoThrow(L, 1); + lua::call_nothrow(L, 1); } }; } @@ -140,7 +139,7 @@ doublesupplier scripting::create_number_supplier( return [=](){ if (auto L = processCallback(env, src, file)) { if (lua_isfunction(L, -1)) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } auto x = lua_tonumber(L, -1); lua::pop(L); @@ -160,7 +159,7 @@ int_array_consumer scripting::create_int_array_consumer( for (uint i = 0; i < len; i++) { lua::pushinteger(L, arr[i]); } - lua::callNoThrow(L, len); + lua::call_nothrow(L, len); } }; } @@ -173,7 +172,7 @@ vec2supplier scripting::create_vec2_supplier( return [=]() { if (auto L = processCallback(env, src, file)) { if (lua_isfunction(L, -1)) { - lua::callNoThrow(L, 0); + lua::call_nothrow(L, 0); } auto y = lua_tonumber(L, -1); lua::pop(L); auto x = lua_tonumber(L, -1); lua::pop(L); diff --git a/src/logic/scripting/scripting_hud.cpp b/src/logic/scripting/scripting_hud.cpp index c1853dad..ebcb0642 100644 --- a/src/logic/scripting/scripting_hud.cpp +++ b/src/logic/scripting/scripting_hud.cpp @@ -24,7 +24,7 @@ void scripting::on_frontend_init(Hud* hud) { scripting::hud = hud; state->openlib(state->getMainThread(), "hud", hudlib); - for (auto& pack : scripting::engine->getContentPacks()) { + for (auto& pack : engine->getContentPacks()) { state->emitEvent(state->getMainThread(), pack.id + ".hudopen", [&] (lua_State* L) { return lua::pushinteger(L, hud->getPlayer()->getId()); @@ -33,7 +33,7 @@ void scripting::on_frontend_init(Hud* hud) { } void scripting::on_frontend_close() { - for (auto& pack : scripting::engine->getContentPacks()) { + for (auto& pack : engine->getContentPacks()) { state->emitEvent(state->getMainThread(), pack.id + ".hudclose", [&] (lua_State* L) { return lua::pushinteger(L, hud->getPlayer()->getId()); @@ -47,9 +47,7 @@ void scripting::load_hud_script(const scriptenv& senv, const std::string& packid std::string src = files::read_string(file); logger.info() << "loading script " << file.u8string(); - auto L = state->getMainThread(); - state->loadbuffer(L, env, src, file.u8string()); - lua::callNoThrow(L, 0); + lua::execute(state->getMainThread(), env, src, file.u8string()); register_event(env, "init", packid+".init"); register_event(env, "on_hud_open", packid+".hudopen");