From 086bcec9c23c197261eb3fb79e841b137d953410 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 19 Feb 2024 12:58:29 +0300 Subject: [PATCH 01/13] critical lua fixes --- src/items/Inventories.cpp | 1 + src/items/Inventory.cpp | 4 ++++ src/items/Inventory.h | 2 ++ src/logic/scripting/lua/LuaState.cpp | 2 +- src/logic/scripting/lua/LuaState.h | 2 +- src/logic/scripting/lua/libgui.cpp | 15 +++++++++++++-- src/logic/scripting/lua/libgui.h | 10 ++++++---- src/logic/scripting/lua/lua_util.h | 6 ++++-- src/logic/scripting/scripting_functional.cpp | 6 +++++- 9 files changed, 37 insertions(+), 11 deletions(-) diff --git a/src/items/Inventories.cpp b/src/items/Inventories.cpp index 53167093..07b33706 100644 --- a/src/items/Inventories.cpp +++ b/src/items/Inventories.cpp @@ -51,6 +51,7 @@ std::shared_ptr Inventories::clone(int64_t id) { auto origptr = reinterpret_cast(original.get()); auto clone = std::make_shared(*origptr); clone->setId(level.getWorld()->getNextInventoryId()); + store(clone); return clone; } diff --git a/src/items/Inventory.cpp b/src/items/Inventory.cpp index 256e9083..1e682e11 100644 --- a/src/items/Inventory.cpp +++ b/src/items/Inventory.cpp @@ -5,6 +5,10 @@ Inventory::Inventory(int64_t id, size_t size) : id(id), slots(size) { } +Inventory::Inventory(const Inventory& orig) { + this->slots = orig.slots; +} + ItemStack& Inventory::getSlot(size_t index) { return slots.at(index); } diff --git a/src/items/Inventory.h b/src/items/Inventory.h index 68226598..677f8d9a 100644 --- a/src/items/Inventory.h +++ b/src/items/Inventory.h @@ -19,6 +19,8 @@ class Inventory : Serializable { public: Inventory(int64_t id, size_t size); + Inventory(const Inventory& orig); + ItemStack& getSlot(size_t index); size_t findEmptySlot(size_t begin=0, size_t end=-1) const; size_t findSlotByItem(itemid_t id, size_t begin=0, size_t end=-1); diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index 381d4edc..ff0bca6d 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -33,7 +33,7 @@ lua::LuaState::LuaState() { setglobal(envName(0)); } -const std::string lua::LuaState::envName(int env) const { +const std::string lua::LuaState::envName(int env) { return "_ENV"+util::mangleid(env); } diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index 8c76f233..bff884d3 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -25,7 +25,7 @@ namespace lua { LuaState(); ~LuaState(); - const std::string envName(int env) const; + static const std::string envName(int env); void loadbuffer(int env, const std::string& src, const std::string& file); int gettop() const; int pushivec3(luaint x, luaint y, luaint z); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index d8b8f960..6819ee4f 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -3,6 +3,7 @@ #include #include "../scripting.h" #include "lua_util.h" +#include "LuaState.h" #include "../../../engine.h" #include "../../../assets/Assets.h" @@ -97,9 +98,9 @@ int l_gui_setattr(lua_State* L) { auto node = getDocumentNode(L, docname, element); if (attr == "pos") { - node->setCoord(lua::tovec2(L, 1)); + node->setCoord(lua::tovec2(L, 4)); } else if (attr == "size") { - node->setSize(lua::tovec2(L, 1)); + node->setSize(lua::tovec2(L, 4)); } else { if (setattr(L, dynamic_cast(node), attr)) return 0; @@ -108,3 +109,13 @@ int l_gui_setattr(lua_State* L) { } return 0; } + +int l_gui_get_env(lua_State* L) { + auto name = lua_tostring(L, 1); + auto doc = scripting::engine->getAssets()->getLayout(name); + if (doc == nullptr) { + luaL_error(L, "document '%s' not found", name); + } + lua_getglobal(L, lua::LuaState::envName(doc->getEnvironment()).c_str()); + return 1; +} diff --git a/src/logic/scripting/lua/libgui.h b/src/logic/scripting/lua/libgui.h index 056b40ea..bbc225b8 100644 --- a/src/logic/scripting/lua/libgui.h +++ b/src/logic/scripting/lua/libgui.h @@ -1,16 +1,18 @@ #ifndef LOGIC_SCRIPTING_API_LIBGUI_H_ #define LOGIC_SCRIPTING_API_LIBGUI_H_ -#include +#include "lua_commons.h" extern int l_gui_getviewport(lua_State* L); extern int l_gui_getattr(lua_State* L); extern int l_gui_setattr(lua_State* L); +extern int l_gui_get_env(lua_State* L); static const luaL_Reg guilib [] = { - {"get_viewport", l_gui_getviewport}, - {"getattr", l_gui_getattr}, - {"setattr", l_gui_setattr}, + {"get_viewport", lua_wrap_errors}, + {"getattr", lua_wrap_errors}, + {"setattr", lua_wrap_errors}, + {"get_env", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/lua_util.h b/src/logic/scripting/lua/lua_util.h index fa750fb9..55fa43fe 100644 --- a/src/logic/scripting/lua/lua_util.h +++ b/src/logic/scripting/lua/lua_util.h @@ -87,10 +87,12 @@ namespace lua { } inline glm::vec2 tovec2(lua_State* L, int idx) { - lua_rawgeti(L, idx, 1); + lua_pushvalue(L, idx); + lua_rawgeti(L, -1, 1); lua::luanumber x = lua_tonumber(L, -1); lua_pop(L, -1); - lua_rawgeti(L, idx, 1); + lua_rawgeti(L, -2, 2); lua::luanumber y = lua_tonumber(L, -1); lua_pop(L, -1); + lua_pop(L, -1); return glm::vec2(x, y); } } diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index 520de0a0..e075590b 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -17,7 +17,11 @@ runnable scripting::create_runnable( const std::string& file ) { return [=](){ - state->execute(env, src, file); + try { + state->execute(env, src, file); + } catch (const lua::luaerror& err) { + std::cerr << err.what() << std::endl; + } }; } From 164d6400d9112149e80f5f80ecf5d1a20bffeaef Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 19 Feb 2024 13:30:32 +0300 Subject: [PATCH 02/13] block ui on block break fix --- src/frontend/hud.cpp | 11 ++++++++++- src/frontend/hud.h | 1 + 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index cd94dd65..94512afd 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -1,5 +1,7 @@ #include "hud.h" +// TODO: refactor this garbage + #include #include #include @@ -365,11 +367,17 @@ void Hud::update(bool visible) { Events::toggleCursor(); } + if (blockUI) { + voxel* vox = level->chunks->get(currentblock.x, currentblock.y, currentblock.z); + if (vox == nullptr || vox->id != currentblockid) { + closeInventory(); + } + } + glm::vec2 invSize = contentAccessPanel->getSize(); contentAccessPanel->setVisible(inventoryOpen); contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height)); contentAccess->setMinSize(glm::vec2(1, Window::height)); - // hotbarView->setVisible(visible && !inventoryOpen); for (int i = keycode::NUM_1; i <= keycode::NUM_9; i++) { if (Events::jpressed(i)) { @@ -437,6 +445,7 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptrbind(blockinv, frontend, interaction.get()); currentblock = block; + currentblockid = level->chunks->get(block.x, block.y, block.z)->id; add(HudElement(hud_element_mode::inventory_bound, doc, blockUI, false)); } diff --git a/src/frontend/hud.h b/src/frontend/hud.h index aa7b2e9c..7e9e2153 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -90,6 +90,7 @@ class Hud { std::shared_ptr inventoryView = nullptr; std::shared_ptr blockUI = nullptr; glm::ivec3 currentblock {}; + blockid_t currentblockid = 0; std::shared_ptr createDebugPanel(Engine* engine); std::shared_ptr createContentAccess(); From 7792c1a6f40598460fb029d62580a10a308d46ce Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 19 Feb 2024 14:13:06 +0300 Subject: [PATCH 03/13] a huge pile of boilerplate code --- src/frontend/gui/controls.cpp | 58 ++++++++++++++++++++++++ src/frontend/gui/controls.h | 18 +++++++- src/frontend/gui/gui_xml.cpp | 17 ++++++- src/logic/scripting/lua/libgui.cpp | 71 ++++++++++++++++++++++++++++++ src/logic/scripting/lua/lua_util.h | 17 +++++++ 5 files changed, 179 insertions(+), 2 deletions(-) diff --git a/src/frontend/gui/controls.cpp b/src/frontend/gui/controls.cpp index 9979b6f1..3e68f392 100644 --- a/src/frontend/gui/controls.cpp +++ b/src/frontend/gui/controls.cpp @@ -150,6 +150,14 @@ std::wstring Button::getText() const { return L""; } +glm::vec4 Button::getPressedColor() const { + return pressedColor; +} + +void Button::setPressedColor(glm::vec4 color) { + pressedColor = color; +} + Button* Button::textSupplier(wstringsupplier supplier) { if (label) { label->textSupplier(supplier); @@ -402,6 +410,7 @@ TrackBar::TrackBar(double min, step(step), trackWidth(trackWidth) { setColor(glm::vec4(0.f, 0.f, 0.f, 0.4f)); + setHoverColor(glm::vec4(0.01f, 0.02f, 0.03f, 0.5f)); } void TrackBar::draw(const GfxContext* pctx, Assets* assets) { @@ -444,6 +453,55 @@ void TrackBar::mouseMove(GUI*, int x, int y) { } } + +double TrackBar::getValue() const { + return value; +} + +double TrackBar::getMin() const { + return min; +} + +double TrackBar::getMax() const { + return max; +} + +double TrackBar::getStep() const { + return step; +} + +int TrackBar::getTrackWidth() const { + return trackWidth; +} + +glm::vec4 TrackBar::getTrackColor() const { + return trackColor; +} + +void TrackBar::setValue(double x) { + value = x; +} + +void TrackBar::setMin(double x) { + min = x; +} + +void TrackBar::setMax(double x) { + max = x; +} + +void TrackBar::setStep(double x) { + step = x; +} + +void TrackBar::setTrackWidth(int width) { + trackWidth = width; +} + +void TrackBar::setTrackColor(glm::vec4 color) { + trackColor = color; +} + // ================================ CheckBox ================================== CheckBox::CheckBox(bool checked) : UINode(glm::vec2(), glm::vec2(32.0f)), checked(checked) { setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f)); diff --git a/src/frontend/gui/controls.h b/src/frontend/gui/controls.h index 72aeb5cd..fd62f0db 100644 --- a/src/frontend/gui/controls.h +++ b/src/frontend/gui/controls.h @@ -72,6 +72,9 @@ namespace gui { virtual void setText(std::wstring text); virtual std::wstring getText() const; + virtual glm::vec4 getPressedColor() const; + virtual void setPressedColor(glm::vec4 color); + virtual Button* textSupplier(wstringsupplier supplier); virtual void refresh() override; @@ -144,7 +147,6 @@ namespace gui { class TrackBar : public UINode { protected: - glm::vec4 hoverColor {0.01f, 0.02f, 0.03f, 0.5f}; glm::vec4 trackColor {1.0f, 1.0f, 1.0f, 0.4f}; doublesupplier supplier = nullptr; doubleconsumer consumer = nullptr; @@ -165,6 +167,20 @@ namespace gui { virtual void setConsumer(doubleconsumer consumer); virtual void mouseMove(GUI*, int x, int y) override; + + virtual double getValue() const; + virtual double getMin() const; + virtual double getMax() const; + virtual double getStep() const; + virtual int getTrackWidth() const; + virtual glm::vec4 getTrackColor() const; + + virtual void setValue(double); + virtual void setMin(double); + virtual void setMax(double); + virtual void setStep(double); + virtual void setTrackWidth(int); + virtual void setTrackColor(glm::vec4); }; class CheckBox : public UINode { diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index bb1923da..bb218568 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -32,7 +32,13 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no node.setSize(element->attr("size").asVec2()); } if (element->has("color")) { - node.setColor(element->attr("color").asColor()); + glm::vec4 color = element->attr("color").asColor(); + glm::vec4 hoverColor = color; + if (element->has("hover-color")) { + hoverColor = node.getHoverColor(); + } + node.setColor(color); + node.setHoverColor(hoverColor); } if (element->has("margin")) { node.setMargin(element->attr("margin").asVec4()); @@ -54,6 +60,9 @@ static void _readUINode(UiXmlReader& reader, xml::xmlelement element, UINode& no ); node.setPositionFunc(supplier); } + if (element->has("hover-color")) { + node.setHoverColor(element->attr("hover-color").asColor()); + } std::string alignName = element->attr("align", "").getText(); node.setAlign(align_from_string(alignName, node.getAlign())); } @@ -163,6 +172,9 @@ static std::shared_ptr readButton(UiXmlReader& reader, xml::xmlelement e if (element->has("text-align")) { button->setTextAlign(align_from_string(element->attr("text-align").getText(), button->getTextAlign())); } + if (element->has("pressed-color")) { + button->setPressedColor(element->attr("pressed-color").asColor()); + } return button; } @@ -216,6 +228,9 @@ static std::shared_ptr readTrackBar(UiXmlReader& reader, xml::xmlelement ); bar->setSupplier(supplier); } + if (element->has("track-color")) { + bar->setTrackColor(element->attr("track-color").asColor()); + } return bar; } diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 6819ee4f..321e518f 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -24,12 +24,61 @@ static gui::UINode* getDocumentNode(lua_State* L, const std::string& name, const return node.get(); } +static bool getattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) { + if (bar == nullptr) + return false; + if (attr == "value") { + lua_pushnumber(L, bar->getValue()); return true; + } else if (attr == "min") { + lua_pushnumber(L, bar->getMin()); return true; + } else if (attr == "max") { + lua_pushnumber(L, bar->getMax()); + return true; + } else if (attr == "step") { + lua_pushnumber(L, bar->getStep()); + return true; + } else if (attr == "trackWidth") { + lua_pushnumber(L, bar->getTrackWidth()); + return true; + } else if (attr == "trackColor") { + return lua::pushcolor_arr(L, bar->getTrackColor()); + } + return false; +} + +static bool setattr(lua_State* L, gui::TrackBar* bar, const std::string& attr) { + if (bar == nullptr) + return false; + if (attr == "value") { + bar->setValue(lua_tonumber(L, 4)); + return true; + } else if (attr == "min") { + bar->setMin(lua_tonumber(L, 4)); + return true; + } else if (attr == "max") { + bar->setMax(lua_tonumber(L, 4)); + return true; + } else if (attr == "step") { + bar->setStep(lua_tonumber(L, 4)); + return true; + } else if (attr == "trackWidth") { + bar->setTrackWidth(lua_tonumber(L, 4)); + return true; + } else if (attr == "trackColor") { + bar->setTrackColor(lua::tocolor(L, 4)); + return true; + } + return false; +} + static bool getattr(lua_State* L, gui::Button* button, const std::string& attr) { if (button == nullptr) return false; if (attr == "text") { lua_pushstring(L, util::wstr2str_utf8(button->getText()).c_str()); return true; + } else if (attr == "pressedColor") { + return lua::pushcolor_arr(L, button->getPressedColor()); } return false; } @@ -50,6 +99,8 @@ static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) if (attr == "text") { button->setText(util::str2wstr_utf8(lua_tostring(L, 4))); return true; + } else if (attr == "pressedColor") { + button->setPressedColor(lua::tocolor(L, 4)); } return false; } @@ -76,12 +127,22 @@ int l_gui_getattr(lua_State* L) { return lua::pushvec2_arr(L, node->getCoord()); } else if (attr == "size") { return lua::pushvec2_arr(L, node->getSize()); + } else if (attr == "hoverColor") { + return lua::pushcolor_arr(L, node->getHoverColor()); + } else if (attr == "interactive") { + lua_pushboolean(L, node->isInteractive()); + return 1; + } else if (attr == "visible") { + lua_pushboolean(L, node->isVisible()); + return 1; } if (getattr(L, dynamic_cast(node), attr)) return 1; if (getattr(L, dynamic_cast(node), attr)) return 1; + if (getattr(L, dynamic_cast(node), attr)) + return 1; return 0; } @@ -101,11 +162,21 @@ int l_gui_setattr(lua_State* L) { node->setCoord(lua::tovec2(L, 4)); } else if (attr == "size") { node->setSize(lua::tovec2(L, 4)); + } else if (attr == "color") { + node->setColor(lua::tocolor(L, 4)); + } else if (attr == "hoverColor") { + node->setHoverColor(lua::tocolor(L, 4)); + } else if (attr == "interactive") { + node->setInteractive(lua_toboolean(L, 4)); + } else if (attr == "visible") { + node->setVisible(lua_toboolean(L, 4)); } else { if (setattr(L, dynamic_cast(node), attr)) return 0; if (setattr(L, dynamic_cast(node), attr)) return 0; + if (setattr(L, dynamic_cast(node), attr)) + return 0; } return 0; } diff --git a/src/logic/scripting/lua/lua_util.h b/src/logic/scripting/lua/lua_util.h index 55fa43fe..caa66d30 100644 --- a/src/logic/scripting/lua/lua_util.h +++ b/src/logic/scripting/lua/lua_util.h @@ -95,6 +95,23 @@ namespace lua { lua_pop(L, -1); return glm::vec2(x, y); } + + inline glm::vec4 tocolor(lua_State* L, int idx) { + lua_pushvalue(L, idx); + if (!lua_istable(L, -1)) { + luaL_error(L, "RGBA array required"); + } + lua_rawgeti(L, -1, 1); + lua::luanumber r = lua_tonumber(L, -1); lua_pop(L, -1); + lua_rawgeti(L, -2, 2); + lua::luanumber g = lua_tonumber(L, -1); lua_pop(L, -1); + lua_rawgeti(L, -3, 3); + lua::luanumber b = lua_tonumber(L, -1); lua_pop(L, -1); + lua_rawgeti(L, -4, 4); + lua::luanumber a = lua_tonumber(L, -1); lua_pop(L, -1); + lua_pop(L, -1); + return glm::vec4(r/255, g/255, b/255, a/255); + } } #endif // LOGIC_SCRIPTING_LUA_UTIL_H_ From 5c23b4125da3809a0df8580d665a8ab3cca1b429 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 19 Feb 2024 23:56:39 +0300 Subject: [PATCH 04/13] even more boilerplate code --- src/frontend/gui/gui_xml.cpp | 36 +++++++++++ src/logic/scripting/lua/LuaState.cpp | 10 +++ src/logic/scripting/lua/LuaState.h | 2 + src/logic/scripting/lua/api_lua.cpp | 55 ----------------- src/logic/scripting/lua/api_lua.h | 16 ----- src/logic/scripting/lua/libgui.cpp | 24 ++++++++ src/logic/scripting/lua/libplayer.cpp | 64 ++++++++++++++++++++ src/logic/scripting/lua/libplayer.h | 22 +++++++ src/logic/scripting/lua/lua_commons.h | 2 +- src/logic/scripting/scripting_functional.cpp | 43 +++++++++++++ src/logic/scripting/scripting_functional.h | 18 ++++++ 11 files changed, 220 insertions(+), 72 deletions(-) create mode 100644 src/logic/scripting/lua/libplayer.cpp create mode 100644 src/logic/scripting/lua/libplayer.h diff --git a/src/frontend/gui/gui_xml.cpp b/src/frontend/gui/gui_xml.cpp index bb218568..5a75e3ad 100644 --- a/src/frontend/gui/gui_xml.cpp +++ b/src/frontend/gui/gui_xml.cpp @@ -178,6 +178,32 @@ static std::shared_ptr readButton(UiXmlReader& reader, xml::xmlelement e return button; } +static std::shared_ptr readCheckBox(UiXmlReader& reader, xml::xmlelement element) { + auto text = readAndProcessInnerText(element); + bool checked = element->attr("checked", "false").asBool(); + auto checkbox = std::make_shared(text, glm::vec2(), checked); + _readPanel(reader, element, *checkbox); + + if (element->has("consumer")) { + auto consumer = scripting::create_bool_consumer( + reader.getEnvironment().getId(), + element->attr("consumer").getText(), + reader.getFilename()+".lua" + ); + checkbox->setConsumer(consumer); + } + + if (element->has("supplier")) { + auto supplier = scripting::create_bool_supplier( + reader.getEnvironment().getId(), + element->attr("supplier").getText(), + reader.getFilename()+".lua" + ); + checkbox->setSupplier(supplier); + } + return checkbox; +} + static std::shared_ptr readTextBox(UiXmlReader& reader, xml::xmlelement element) { auto placeholder = util::str2wstr_utf8(element->attr("placeholder", "").getText()); auto text = readAndProcessInnerText(element); @@ -193,6 +219,15 @@ static std::shared_ptr readTextBox(UiXmlReader& reader, xml::xmlelement ); textbox->setTextConsumer(consumer); } + + if (element->has("supplier")) { + auto supplier = scripting::create_wstring_supplier( + reader.getEnvironment().getId(), + element->attr("consumer").getText(), + reader.getFilename()+".lua" + ); + textbox->setTextSupplier(supplier); + } return textbox; } @@ -242,6 +277,7 @@ UiXmlReader::UiXmlReader(const scripting::Environment& env, AssetsLoader& assets add("panel", readPanel); add("button", readButton); add("textbox", readTextBox); + add("chackbox", readCheckBox); add("trackbar", readTrackBar); add("container", readContainer); } diff --git a/src/logic/scripting/lua/LuaState.cpp b/src/logic/scripting/lua/LuaState.cpp index ff0bca6d..68fe1ebd 100644 --- a/src/logic/scripting/lua/LuaState.cpp +++ b/src/logic/scripting/lua/LuaState.cpp @@ -4,6 +4,7 @@ #include "lua_util.h" #include "api_lua.h" #include "libgui.h" +#include "libplayer.h" #include "libinventory.h" #include "../../../util/stringutil.h" @@ -172,6 +173,11 @@ int lua::LuaState::pushnumber(luanumber x) { return 1; } +int lua::LuaState::pushboolean(bool x) { + lua_pushboolean(L, x); + return 1; +} + int lua::LuaState::pushivec3(luaint x, luaint y, luaint z) { lua::pushivec3(L, x, y, z); return 3; @@ -233,6 +239,10 @@ lua::luanumber lua::LuaState::tonumber(int idx) { return lua_tonumber(L, idx); } +const char* lua::LuaState::tostring(int idx) { + return lua_tostring(L, idx); +} + void lua::LuaState::openlib(const std::string& name, const luaL_Reg* libfuncs, int nup) { lua_newtable(L); luaL_setfuncs(L, libfuncs, nup); diff --git a/src/logic/scripting/lua/LuaState.h b/src/logic/scripting/lua/LuaState.h index bff884d3..b80d2aab 100644 --- a/src/logic/scripting/lua/LuaState.h +++ b/src/logic/scripting/lua/LuaState.h @@ -31,6 +31,7 @@ namespace lua { int pushivec3(luaint x, luaint y, luaint z); int pushinteger(luaint x); int pushnumber(luanumber x); + int pushboolean(bool x); int pushstring(const std::string& str); int pushenv(int env); int pushvalue(int idx); @@ -42,6 +43,7 @@ namespace lua { bool toboolean(int idx); luaint tointeger(int idx); luanumber tonumber(int idx); + const char* tostring(int idx); int call(int argc); int callNoThrow(int argc); int execute(int env, const std::string& src, const std::string& file=""); diff --git a/src/logic/scripting/lua/api_lua.cpp b/src/logic/scripting/lua/api_lua.cpp index 88835056..dd47dab4 100644 --- a/src/logic/scripting/lua/api_lua.cpp +++ b/src/logic/scripting/lua/api_lua.cpp @@ -142,61 +142,6 @@ int l_world_get_seed(lua_State* L) { return 1; } -/* == player library ==*/ -int l_player_get_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec3 pos = scripting::level->player->hitbox->position; - lua_pushnumber(L, pos.x); - lua_pushnumber(L, pos.y); - lua_pushnumber(L, pos.z); - return 3; -} - -int l_player_get_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - glm::vec2 rot = scripting::level->player->cam; - lua_pushnumber(L, rot.x); - lua_pushnumber(L, rot.y); - return 2; -} - -int l_player_set_rot(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - glm::vec2& cam = scripting::level->player->cam; - cam.x = x; - cam.y = y; - return 0; -} - -int l_player_set_pos(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - lua::luanumber x = lua_tonumber(L, 2); - lua::luanumber y = lua_tonumber(L, 3); - lua::luanumber z = lua_tonumber(L, 4); - scripting::level->player->hitbox->position = glm::vec3(x, y, z); - return 0; -} - -int l_player_get_inv(lua_State* L) { - int playerid = lua_tointeger(L, 1); - if (playerid != 1) - return 0; - Player* player = scripting::level->player; - lua_pushinteger(L, player->getInventory()->getId()); - lua_pushinteger(L, player->getChosenSlot()); - return 2; -} - /* == item library == */ int l_item_name(lua_State* L) { auto indices = scripting::content->getIndices(); diff --git a/src/logic/scripting/lua/api_lua.h b/src/logic/scripting/lua/api_lua.h index ea809ceb..27fd4c85 100644 --- a/src/logic/scripting/lua/api_lua.h +++ b/src/logic/scripting/lua/api_lua.h @@ -58,22 +58,6 @@ static const luaL_Reg worldlib [] = { {NULL, NULL} }; -/* == player library ==*/ -extern int l_player_get_pos(lua_State* L); -extern int l_player_get_rot(lua_State* L); -extern int l_player_set_rot(lua_State* L); -extern int l_player_set_pos(lua_State* L); -extern int l_player_get_inv(lua_State* L); - -static const luaL_Reg playerlib [] = { - {"get_pos", lua_wrap_errors}, - {"set_pos", lua_wrap_errors}, - {"get_rot", lua_wrap_errors}, - {"set_rot", lua_wrap_errors}, - {"get_inventory", lua_wrap_errors}, - {NULL, NULL} -}; - /* == item library == */ extern int l_item_name(lua_State* L); extern int l_item_index(lua_State* L); diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 321e518f..cdcc6561 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -93,6 +93,16 @@ static bool getattr(lua_State* L, gui::Label* label, const std::string& attr) { return false; } +static bool getattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) { + if (box == nullptr) + return false; + if (attr == "checked") { + lua_pushboolean(L, box->isChecked()); + return true; + } + return false; +} + static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) { if (button == nullptr) return false; @@ -105,6 +115,16 @@ static bool setattr(lua_State* L, gui::Button* button, const std::string& attr) return false; } +static bool setattr(lua_State* L, gui::FullCheckBox* box, const std::string& attr) { + if (box == nullptr) + return false; + if (attr == "checked") { + box->setChecked(lua_toboolean(L, 4)); + return true; + } + return false; +} + static bool setattr(lua_State* L, gui::Label* label, const std::string& attr) { if (label == nullptr) return false; @@ -143,6 +163,8 @@ int l_gui_getattr(lua_State* L) { return 1; if (getattr(L, dynamic_cast(node), attr)) return 1; + if (getattr(L, dynamic_cast(node), attr)) + return 1; return 0; } @@ -177,6 +199,8 @@ int l_gui_setattr(lua_State* L) { return 0; if (setattr(L, dynamic_cast(node), attr)) return 0; + if (setattr(L, dynamic_cast(node), attr)) + return 0; } return 0; } diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp new file mode 100644 index 00000000..cbf1fe47 --- /dev/null +++ b/src/logic/scripting/lua/libplayer.cpp @@ -0,0 +1,64 @@ +#include "libplayer.h" +#include "../scripting.h" +#include "../../../world/Level.h" +#include "../../../objects/Player.h" +#include "../../../physics/Hitbox.h" +#include "../../../window/Camera.h" +#include "../../../items/Inventory.h" + +#include + +/* == player library ==*/ +int l_player_get_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec3 pos = scripting::level->player->hitbox->position; + lua_pushnumber(L, pos.x); + lua_pushnumber(L, pos.y); + lua_pushnumber(L, pos.z); + return 3; +} + +int l_player_get_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + glm::vec2 rot = scripting::level->player->cam; + lua_pushnumber(L, rot.x); + lua_pushnumber(L, rot.y); + return 2; +} + +int l_player_set_rot(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + glm::vec2& cam = scripting::level->player->cam; + cam.x = x; + cam.y = y; + return 0; +} + +int l_player_set_pos(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + lua::luanumber x = lua_tonumber(L, 2); + lua::luanumber y = lua_tonumber(L, 3); + lua::luanumber z = lua_tonumber(L, 4); + scripting::level->player->hitbox->position = glm::vec3(x, y, z); + return 0; +} + +int l_player_get_inv(lua_State* L) { + int playerid = lua_tointeger(L, 1); + if (playerid != 1) + return 0; + Player* player = scripting::level->player; + lua_pushinteger(L, player->getInventory()->getId()); + lua_pushinteger(L, player->getChosenSlot()); + return 2; +} diff --git a/src/logic/scripting/lua/libplayer.h b/src/logic/scripting/lua/libplayer.h new file mode 100644 index 00000000..e53b83b8 --- /dev/null +++ b/src/logic/scripting/lua/libplayer.h @@ -0,0 +1,22 @@ +#ifndef LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ +#define LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ + +#include "lua_commons.h" + +/* == player library ==*/ +extern int l_player_get_pos(lua_State* L); +extern int l_player_get_rot(lua_State* L); +extern int l_player_set_rot(lua_State* L); +extern int l_player_set_pos(lua_State* L); +extern int l_player_get_inv(lua_State* L); + +static const luaL_Reg playerlib [] = { + {"get_pos", lua_wrap_errors}, + {"set_pos", lua_wrap_errors}, + {"get_rot", lua_wrap_errors}, + {"set_rot", lua_wrap_errors}, + {"get_inventory", lua_wrap_errors}, + {NULL, NULL} +}; + +#endif // LOGIC_SCRIPTING_LUA_LIBPLAYER_H_ diff --git a/src/logic/scripting/lua/lua_commons.h b/src/logic/scripting/lua/lua_commons.h index c139be40..4732662d 100644 --- a/src/logic/scripting/lua/lua_commons.h +++ b/src/logic/scripting/lua/lua_commons.h @@ -25,4 +25,4 @@ template int lua_wrap_errors(lua_State *L) { return result; } -#endif // LOGIC_SCRIPTING_LUA_H_ \ No newline at end of file +#endif // LOGIC_SCRIPTING_LUA_H_ diff --git a/src/logic/scripting/scripting_functional.cpp b/src/logic/scripting/scripting_functional.cpp index e075590b..619d751a 100644 --- a/src/logic/scripting/scripting_functional.cpp +++ b/src/logic/scripting/scripting_functional.cpp @@ -51,6 +51,49 @@ wstringconsumer scripting::create_wstring_consumer( }; } +wstringsupplier scripting::create_wstring_supplier( + int env, + const std::string& src, + const std::string& file +) { + return [=](){ + if (processCallback(env, src, file)) { + state->callNoThrow(0); + auto str = state->tostring(-1); state->pop(); + return util::str2wstr_utf8(str); + } + return std::wstring(L""); + }; +} + +boolconsumer scripting::create_bool_consumer( + int env, + const std::string& src, + const std::string& file +) { + return [=](bool x){ + if (processCallback(env, src, file)) { + state->pushboolean(x); + state->callNoThrow(1); + } + }; +} + +boolsupplier scripting::create_bool_supplier( + int env, + const std::string& src, + const std::string& file +) { + return [=](){ + if (processCallback(env, src, file)) { + state->callNoThrow(0); + bool x = state->toboolean(-1); state->pop(); + return x; + } + return false; + }; +} + doubleconsumer scripting::create_number_consumer( int env, const std::string& src, diff --git a/src/logic/scripting/scripting_functional.h b/src/logic/scripting/scripting_functional.h index d608eded..c5db97e4 100644 --- a/src/logic/scripting/scripting_functional.h +++ b/src/logic/scripting/scripting_functional.h @@ -18,6 +18,24 @@ namespace scripting { const std::string& file="" ); + wstringsupplier create_wstring_supplier( + int env, + const std::string& src, + const std::string& file="" + ); + + boolconsumer create_bool_consumer( + int env, + const std::string& src, + const std::string& file="" + ); + + boolsupplier create_bool_supplier( + int env, + const std::string& src, + const std::string& file="" + ); + doubleconsumer create_number_consumer( int env, const std::string& src, From 55f855849e3c72c681ae1de46d78d7fd670cb1d4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 20 Feb 2024 05:27:11 +0300 Subject: [PATCH 05/13] hidden hud mode fix --- src/frontend/hud.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 94512afd..d0a14676 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -374,10 +374,15 @@ void Hud::update(bool visible) { } } + for (auto& element : elements) { + element.getNode()->setVisible(visible); + } + glm::vec2 invSize = contentAccessPanel->getSize(); contentAccessPanel->setVisible(inventoryOpen); contentAccessPanel->setSize(glm::vec2(invSize.x, Window::height)); contentAccess->setMinSize(glm::vec2(1, Window::height)); + hotbarView->setVisible(visible); for (int i = keycode::NUM_1; i <= keycode::NUM_9; i++) { if (Events::jpressed(i)) { @@ -396,10 +401,12 @@ void Hud::update(bool visible) { player->setChosenSlot(slot); } - for (auto& element : elements) { - element.update(pause, inventoryOpen, player->debug); - if (element.isRemoved()) { - remove(element); + if (visible) { + for (auto& element : elements) { + element.update(pause, inventoryOpen, player->debug); + if (element.isRemoved()) { + remove(element); + } } } cleanup(); From e68f62195f8de637296b8503faa32fcd660db5aa Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 20 Feb 2024 06:42:11 +0300 Subject: [PATCH 06/13] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c2151920..f8c94187 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Run with compiled executable file: -[Windows 64 bit](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v18/voxelengine_v18_win64.zip) +[Windows 64 bit](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v19/voxelengine_v19_win64.zip) -[Linux x86_64 (.AppImage)](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v18/VoxelEngine-0.18-x86_64.AppImage) +[Linux x86_64 (.AppImage)](https://github.com/MihailRis/VoxelEngine-Cpp/releases/download/v19/VoxelEngine-0.19-x86_64.AppImage) # Controls: From 539a79c22cb754a14dee7dd3ec4611040b8d5a38 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 20 Feb 2024 15:18:02 +0300 Subject: [PATCH 07/13] inventory re-saving fix --- src/frontend/hud.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index d0a14676..a09ab7fc 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -29,6 +29,7 @@ #include "../window/input.h" #include "../voxels/Chunks.h" #include "../voxels/Block.h" +#include "../voxels/Chunk.h" #include "../world/World.h" #include "../world/Level.h" #include "../objects/Player.h" @@ -450,6 +451,7 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptrinventories->createVirtual(blockUI->getSlotsCount()); } + level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true); blockUI->bind(blockinv, frontend, interaction.get()); currentblock = block; currentblockid = level->chunks->get(block.x, block.y, block.z)->id; From 052ad45a6fd731e55cc4943f3fae2bd1e001014c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 20 Feb 2024 18:39:36 +0300 Subject: [PATCH 08/13] virtual inventory fix --- src/frontend/hud.cpp | 2 -- src/logic/scripting/lua/libhud.cpp | 7 ------- 2 files changed, 9 deletions(-) diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index a09ab7fc..860131a2 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -447,8 +447,6 @@ void Hud::openInventory(glm::ivec3 block, UiDocument* doc, std::shared_ptrinventories->createVirtual(blockUI->getSlotsCount()); } level->chunks->getChunkByVoxel(block.x, block.y, block.z)->setUnsaved(true); diff --git a/src/logic/scripting/lua/libhud.cpp b/src/logic/scripting/lua/libhud.cpp index 207daa6f..84c1d236 100644 --- a/src/logic/scripting/lua/libhud.cpp +++ b/src/logic/scripting/lua/libhud.cpp @@ -53,13 +53,6 @@ int l_hud_open_block(lua_State* L) { } auto id = scripting::blocks->createBlockInventory(x, y, z); - if (id == 0) { - luaL_error(L, - "block '%s' at %d %d %d has no inventory", - def->name.c_str(), - x, y, z - ); - } scripting::hud->openInventory( glm::ivec3(x, y, z), layout, scripting::level->inventories->get(id) From 399bd9c362a32658957d5d05bdee46eae145f919 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Tue, 20 Feb 2024 20:55:45 +0300 Subject: [PATCH 09/13] removed garbage from inventory.xml --- res/layouts/inventory.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/layouts/inventory.xml b/res/layouts/inventory.xml index 6d2fc761..4291ab4d 100644 --- a/res/layouts/inventory.xml +++ b/res/layouts/inventory.xml @@ -1,4 +1,4 @@ - + From 27da72973ee68da8e0b34555cdb0a6f2c954ae73 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 21 Feb 2024 09:05:25 +0300 Subject: [PATCH 10/13] small optimization --- src/graphics/BlocksRenderer.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/graphics/BlocksRenderer.cpp b/src/graphics/BlocksRenderer.cpp index 70271c31..14bdf0cd 100644 --- a/src/graphics/BlocksRenderer.cpp +++ b/src/graphics/BlocksRenderer.cpp @@ -102,13 +102,9 @@ void BlocksRenderer::face(const vec3& coord, void BlocksRenderer::vertex(const vec3& coord, float u, float v, const vec4& tint, - const vec3& X, - const vec3& Y, - const vec3& Z) { - // TODO: optimize - vec3 axisX = glm::normalize(X); - vec3 axisY = glm::normalize(Y); - vec3 axisZ = glm::normalize(Z); + const vec3& axisX, + const vec3& axisY, + const vec3& axisZ) { vec3 pos = coord+axisZ*0.5f+(axisX+axisY)*0.5f; vec4 light = pickSoftLight(ivec3(round(pos.x), round(pos.y), round(pos.z)), axisX, axisY); vertex(coord, u, v, light * tint); @@ -130,11 +126,15 @@ void BlocksRenderer::face(const vec3& coord, float d = glm::dot(Z, SUN_VECTOR); d = 0.8f + d * 0.2f; + vec3 axisX = glm::normalize(X); + vec3 axisY = glm::normalize(Y); + vec3 axisZ = glm::normalize(Z); + vec4 tint(d); - vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, X, Y, Z); - vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, X, Y, Z); - vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, X, Y, Z); - vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, X, Y, Z); + vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint, axisX, axisY, axisZ); + vertex(coord + ( X - Y + Z) * s, region.u2, region.v1, tint, axisX, axisY, axisZ); + vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint, axisX, axisY, axisZ); + vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint, axisX, axisY, axisZ); } else { vec4 tint(1.0f); vertex(coord + (-X - Y + Z) * s, region.u1, region.v1, tint); @@ -142,7 +142,7 @@ void BlocksRenderer::face(const vec3& coord, vertex(coord + ( X + Y + Z) * s, region.u2, region.v2, tint); vertex(coord + (-X + Y + Z) * s, region.u1, region.v2, tint); } - index(0, 1, 2, 0, 2, 3); + index(0, 1, 2, 0, 2, 3); } void BlocksRenderer::tetragonicFace(const vec3& coord, const vec3& p1, From a44a9be28e14529e1393d209a08e9402a53cf02c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 21 Feb 2024 09:08:24 +0300 Subject: [PATCH 11/13] fix --- src/logic/scripting/lua/libplayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logic/scripting/lua/libplayer.cpp b/src/logic/scripting/lua/libplayer.cpp index cbf1fe47..dfb8fc16 100644 --- a/src/logic/scripting/lua/libplayer.cpp +++ b/src/logic/scripting/lua/libplayer.cpp @@ -57,7 +57,7 @@ int l_player_get_inv(lua_State* L) { int playerid = lua_tointeger(L, 1); if (playerid != 1) return 0; - Player* player = scripting::level->player; + auto player = scripting::level->player; lua_pushinteger(L, player->getInventory()->getId()); lua_pushinteger(L, player->getChosenSlot()); return 2; From 241570ac82d4a25d226912cba66aaa191cbf59f4 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 21 Feb 2024 09:09:17 +0300 Subject: [PATCH 12/13] removed extra workflow --- .github/workflows/appimage-wayland.yml | 42 -------------------------- 1 file changed, 42 deletions(-) delete mode 100644 .github/workflows/appimage-wayland.yml diff --git a/.github/workflows/appimage-wayland.yml b/.github/workflows/appimage-wayland.yml deleted file mode 100644 index f59902f7..00000000 --- a/.github/workflows/appimage-wayland.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: C/C++ AppImage (wayland) - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -jobs: - build-appimage: - - strategy: - matrix: - include: - - os: ubuntu-latest - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - with: - submodules: 'true' - - name: install dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential libglfw3-wayland libglfw3-dev libglew-dev libglm-dev libpng-dev libopenal-dev libluajit-5.1-dev cmake squashfs-tools - sudo ln -s /usr/lib/x86_64-linux-gnu/libluajit-5.1.a /usr/lib/x86_64-linux-gnu/liblua5.1.a - sudo ln -s /usr/include/luajit-2.1 /usr/include/lua - - name: configure - run: cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DVOXELENGINE_BUILD_APPDIR=1 - - name: build - run: cmake --build build -t install - - name: Build AppImage - uses: AppImageCrafters/build-appimage-action@fe2205a4d6056be47051f7b1b3811106e9814910 - env: - UPDATE_INFO: gh-releases-zsync|MihailRis|VoxelEngine-Cpp|latest|*x86_64.AppImage.zsync - with: - recipe: dev/AppImageBuilder.yml - - uses: actions/upload-artifact@v2 - with: - name: AppImage - path: './*.AppImage*' From fcb396344c8c4334c824a6826037f78eec241332 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 21 Feb 2024 11:20:53 +0300 Subject: [PATCH 13/13] auto lua modules removal on quit --- res/scripts/stdlib.lua | 32 +++++++++++++++++++------------ src/logic/scripting/scripting.cpp | 3 +++ 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 370d4eef..44e6e3f4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -20,8 +20,10 @@ function parse_path(path) return string.sub(path, 1, index-1), string.sub(path, index+1, -1) end +package = { + loaded={} +} local __cached_scripts = {} -local __cached_results = {} -- Load script with caching -- @@ -31,38 +33,44 @@ local __cached_results = {} -- nocache - ignore cached script, load anyway function load_script(path, nocache) local packname, filename = parse_path(path) - local fullpath = file.resolve(path); -- __cached_scripts used in condition because cached result may be nil - if not nocache and __cached_scripts[fullpath] ~= nil then - return __cached_results[fullpath] + if not nocache and __cached_scripts[path] ~= nil then + return package.loaded[path] end if not file.isfile(path) then error("script '"..filename.."' not found in '"..packname.."'") end - local script, err = loadfile(fullpath) + local script, err = loadfile(file.resolve(path)) if script == nil then error(err) end local result = script() if not nocache then - __cached_scripts[fullpath] = script - __cached_results[fullpath] = result + __cached_scripts[path] = script + package.loaded[path] = result end return result end +function __scripts_cleanup() + print("cleaning scripts cache") + for k, v in pairs(__cached_scripts) do + local packname, _ = parse_path(k) + if packname ~= "core" then + print("unloaded "..k) + __cached_scripts[k] = nil + package.loaded[k] = nil + end + end +end + function require(path) local prefix, file = parse_path(path) return load_script(prefix..":modules/"..file..".lua") end -function __reset_scripts_cache() - __cached_scripts = {} - __cached_results = {} -end - function sleep(timesec) local start = time.uptime() while time.uptime() - start < timesec do diff --git a/src/logic/scripting/scripting.cpp b/src/logic/scripting/scripting.cpp index 26d55047..6ea8da5b 100644 --- a/src/logic/scripting/scripting.cpp +++ b/src/logic/scripting/scripting.cpp @@ -124,6 +124,9 @@ void scripting::on_world_quit() { state->callNoThrow(0); } } + if (state->getglobal("__scripts_cleanup")) { + state->callNoThrow(0); + } scripting::level = nullptr; scripting::content = nullptr; scripting::indices = nullptr;