diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index 15206130..ed014934 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -33,7 +33,6 @@ static void readUINode(xml::xmlelement element, UINode& node) { if (element->has("margin")) { node.setMargin(element->attr("margin").asVec4()); } - std::string alignName = element->attr("align", "").getText(); node.setAlign(align_from_string(alignName, node.getAlign())); } @@ -41,6 +40,9 @@ static void readUINode(xml::xmlelement element, UINode& node) { static void _readContainer(UiXmlReader& reader, xml::xmlelement element, Container& container) { readUINode(element, container); + if (element->has("scrollable")) { + container.setScrollable(element->attr("scrollable").asBool()); + } for (auto& sub : element->getElements()) { if (sub->isText()) continue; @@ -54,11 +56,12 @@ static void _readPanel(UiXmlReader& reader, xml::xmlelement element, Panel& pane if (element->has("padding")) { panel.setPadding(element->attr("padding").asVec4()); } - if (element->has("size")) { panel.setResizing(false); } - + if (element->has("max-length")) { + panel.setMaxLength(element->attr("max-length").asInt()); + } for (auto& sub : element->getElements()) { if (sub->isText()) continue; diff --git a/src/logic/scripting/LuaState.cpp b/src/logic/scripting/LuaState.cpp index 3cd52dec..41561862 100644 --- a/src/logic/scripting/LuaState.cpp +++ b/src/logic/scripting/LuaState.cpp @@ -1,6 +1,41 @@ #include "LuaState.h" #include "api_lua.h" +#include "../../util/stringutil.h" + +lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { +} + +lua::LuaState::LuaState() { + L = luaL_newstate(); + if (L == nullptr) { + throw lua::luaerror("could not to initialize Lua"); + } + // Allowed standard libraries + luaopen_base(L); + luaopen_math(L); + luaopen_string(L); + luaopen_table(L); + + std::cout << LUA_VERSION << std::endl; +# ifdef LUAJIT_VERSION + luaopen_jit(L); + std::cout << LUAJIT_VERSION << std::endl; +# endif // LUAJIT_VERSION + + createFuncs(); + + lua_getglobal(L, "_G"); + lua_setglobal(L, ":G"); +} + +lua::LuaState::~LuaState() { + lua_close(L); +} + +void lua::LuaState::logError(const std::string& text) { + std::cerr << text << std::endl; +} void lua::LuaState::addfunc(const std::string& name, lua_CFunction func) { lua_pushcfunction(L, func); @@ -64,37 +99,6 @@ void lua::LuaState::createFuncs() { addfunc("set_block_user_bits", l_set_block_user_bits); } -lua::luaerror::luaerror(const std::string& message) : std::runtime_error(message) { -} - -lua::LuaState::LuaState() { - L = luaL_newstate(); - if (L == nullptr) { - throw lua::luaerror("could not to initialize Lua"); - } - // Allowed standard libraries - luaopen_base(L); - luaopen_math(L); - luaopen_string(L); - luaopen_table(L); - - std::cout << LUA_VERSION << std::endl; -# ifdef LUAJIT_VERSION - luaopen_jit(L); - std::cout << LUAJIT_VERSION << std::endl; -# endif // LUAJIT_VERSION - - createFuncs(); -} - -lua::LuaState::~LuaState() { - lua_close(L); -} - -void lua::LuaState::logError(const std::string& text) { - std::cerr << text << std::endl; -} - void lua::LuaState::loadbuffer(const std::string& src, const std::string& file) { if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) { throw lua::luaerror(lua_tostring(L, -1)); @@ -122,6 +126,11 @@ int lua::LuaState::eval(const std::string& src, const std::string& file) { return call(0); } +int lua::LuaState::execute(const std::string& src, const std::string& file) { + loadbuffer(src, file); + return callNoThrow(0); +} + int lua::LuaState::gettop() const { return lua_gettop(L); } @@ -162,7 +171,42 @@ void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs, i const std::string lua::LuaState::storeAnonymous() { auto funcId = uintptr_t(lua_topointer(L, lua_gettop(L))); - auto funcName = "F$"+std::to_string(funcId); + auto funcName = "F$"+util::mangleid(funcId); lua_setglobal(L, funcName.c_str()); return funcName; -} \ No newline at end of file +} + +void lua::LuaState::initNamespace() { + lua_getglobal(L, "_G"); + lua_setfield(L, -1, ":G"); +} + +int lua::LuaState::createNamespace() { + int id = nextNamespace++; + + if (currentNamespace != 0) { + setNamespace(0); + } + + lua_createtable(L, 0, 0); + initNamespace(); + setglobal("_N"+util::mangleid(id)); + + setNamespace(id); + return id; +} + +void lua::LuaState::setNamespace(int id) { + if (id == 0) { + getglobal(":G"); + lua_setfenv(L, -1); + } else { + getglobal(":G"); + lua_getfield(L, -1, ("_N"+util::mangleid(id)).c_str()); + if (lua_isnil(L, -1)) { + lua_pop(L, -1); + throw luaerror("namespace "+std::to_string(id)+" was not found"); + } + lua_setfenv(L, -1); + } +} diff --git a/src/logic/scripting/LuaState.h b/src/logic/scripting/LuaState.h index 44f30003..f1073a6e 100644 --- a/src/logic/scripting/LuaState.h +++ b/src/logic/scripting/LuaState.h @@ -16,8 +16,11 @@ namespace lua { class LuaState { lua_State* L; + int nextNamespace = 1; + int currentNamespace = 0; void logError(const std::string& text); + void initNamespace(); public: LuaState(); ~LuaState(); @@ -32,6 +35,7 @@ namespace lua { luaint tointeger(int index); int call(int argc); int callNoThrow(int argc); + int execute(const std::string& src, const std::string& file=""); int eval(const std::string& src, const std::string& file=""); void openlib(const std::string& name, const luaL_Reg* libfuncs, int nup); void addfunc(const std::string& name, lua_CFunction func); @@ -40,6 +44,8 @@ namespace lua { bool rename(const std::string& from, const std::string& to); void remove(const std::string& name);; void createFuncs(); + int createNamespace(); + void setNamespace(int id); const std::string storeAnonymous(); }; diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index f604cd56..4d50f9fc 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -32,9 +32,7 @@ void load_script(fs::path name) { fs::path file = paths->getResources()/fs::path("scripts")/name; std::string src = files::read_string(file); - - state->loadbuffer(src, file.u8string()); - state->callNoThrow(0); + state->execute(src, file.u8string()); } void scripting::initialize(Engine* engine) { @@ -51,8 +49,7 @@ runnable scripting::create_runnable( const std::string& src ) { return [=](){ - state->loadbuffer(src, file); - state->callNoThrow(0); + state->execute(src, file); }; } @@ -189,9 +186,7 @@ bool scripting::on_item_break_block(Player* player, const ItemDef* item, int x, void scripting::load_block_script(std::string prefix, fs::path file, block_funcs_set* funcsset) { std::string src = files::read_string(file); std::cout << "loading script " << file.u8string() << std::endl; - - state->loadbuffer(src, file.u8string()); - state->callNoThrow(0); + state->execute(src, file.u8string()); funcsset->init=state->rename("init", prefix+".init"); funcsset->update=state->rename("on_update", prefix+".update"); @@ -205,8 +200,7 @@ void scripting::load_block_script(std::string prefix, fs::path file, block_funcs void scripting::load_item_script(std::string prefix, fs::path file, item_funcs_set* funcsset) { std::string src = files::read_string(file); std::cout << "loading script " << file.u8string() << std::endl; - state->loadbuffer(src, file.u8string()); - state->callNoThrow(0); + state->execute(src, file.u8string()); funcsset->init=state->rename("init", prefix+".init"); funcsset->on_use_on_block=state->rename("on_use_on_block", prefix+".useon"); funcsset->on_block_break_by=state->rename("on_block_break_by", prefix+".blockbreakby"); diff --git a/src/util/stringutil.cpp b/src/util/stringutil.cpp index 8b587d3b..605eb741 100644 --- a/src/util/stringutil.cpp +++ b/src/util/stringutil.cpp @@ -228,6 +228,14 @@ std::string util::base64_encode(const ubyte* data, size_t size) { return ss.str(); } +std::string util::mangleid(uint64_t value) { + // todo: use base64 + std::stringstream ss; + ss << std::hex << value; + std::string result(ss.str()); + return ss.str(); +} + std::vector util::base64_decode(const char* str, size_t size) { std::vector bytes((size/4)*3); ubyte* dst = bytes.data(); diff --git a/src/util/stringutil.h b/src/util/stringutil.h index 7cd17981..8c30cbc6 100644 --- a/src/util/stringutil.h +++ b/src/util/stringutil.h @@ -27,6 +27,8 @@ namespace util { extern std::vector base64_decode(const char* str, size_t size); extern std::vector base64_decode(const std::string& str); + extern std::string mangleid(uint64_t value); + extern int replaceAll(std::string& str, const std::string& from, const std::string& to); extern double parse_double(const std::string& str);