From b15d234a88a2085632c7a593880031283ce770b0 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 13:49:23 +0300 Subject: [PATCH 1/6] added file.list function --- src/engine.cpp | 2 +- src/files/engine_paths.cpp | 34 ++++++++++++++++++++++++----- src/files/engine_paths.hpp | 10 +++++++-- src/logic/scripting/lua/libfile.cpp | 32 +++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 17c5d976..7fdbedc5 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -259,7 +259,7 @@ void Engine::loadContent() { names = manager.assembly(names); contentPacks = manager.getAll(names); - std::vector> resRoots; + std::vector resRoots; for (auto& pack : contentPacks) { resRoots.push_back({pack.id, pack.folder}); diff --git a/src/files/engine_paths.cpp b/src/files/engine_paths.cpp index f14828b3..509c4055 100644 --- a/src/files/engine_paths.cpp +++ b/src/files/engine_paths.cpp @@ -164,14 +164,14 @@ fs::path EnginePaths::resolve(std::string path) { throw files_access_error("unknown entry point '"+prefix+"'"); } -ResPaths::ResPaths(fs::path mainRoot, std::vector> roots) +ResPaths::ResPaths(fs::path mainRoot, std::vector roots) : mainRoot(mainRoot), roots(roots) { } fs::path ResPaths::find(const std::string& filename) const { for (int i = roots.size()-1; i >= 0; i--) { auto& root = roots[i]; - fs::path file = root.second / fs::u8path(filename); + fs::path file = root.path / fs::u8path(filename); if (fs::exists(file)) { return file; } @@ -182,8 +182,8 @@ fs::path ResPaths::find(const std::string& filename) const { std::string ResPaths::findRaw(const std::string& filename) const { for (int i = roots.size()-1; i >= 0; i--) { auto& root = roots[i]; - if (fs::exists(root.second / fs::path(filename))) { - return root.first+":"+filename; + if (fs::exists(root.path / fs::path(filename))) { + return root.name + ":" + filename; } } auto resDir = mainRoot; @@ -193,11 +193,35 @@ std::string ResPaths::findRaw(const std::string& filename) const { throw std::runtime_error("could not to find file "+util::quote(filename)); } +std::vector ResPaths::listdirRaw(const std::string& folderName) const { + std::vector entries; + for (int i = roots.size()-1; i >= 0; i--) { + auto& root = roots[i]; + fs::path folder = root.path / fs::u8path(folderName); + if (!fs::is_directory(folder)) + continue; + for (const auto& entry : fs::directory_iterator(folder)) { + auto name = entry.path().filename().u8string(); + entries.push_back(root.name+":"+folderName+"/"+name); + } + } + { + fs::path folder = mainRoot / fs::u8path(folderName); + if (!fs::is_directory(folder)) + return entries; + for (const auto& entry : fs::directory_iterator(folder)) { + auto name = entry.path().filename().u8string(); + entries.push_back("core:"+folderName+"/"+name); + } + } + return entries; +} + std::vector ResPaths::listdir(const std::string& folderName) const { std::vector entries; for (int i = roots.size()-1; i >= 0; i--) { auto& root = roots[i]; - fs::path folder = root.second / fs::u8path(folderName); + fs::path folder = root.path / fs::u8path(folderName); if (!fs::is_directory(folder)) continue; for (const auto& entry : fs::directory_iterator(folder)) { diff --git a/src/files/engine_paths.hpp b/src/files/engine_paths.hpp index 41c57e6e..ac1ed5a8 100644 --- a/src/files/engine_paths.hpp +++ b/src/files/engine_paths.hpp @@ -42,18 +42,24 @@ public: fs::path resolve(std::string path); }; +struct PathsRoot { + std::string name; + fs::path path; +}; + class ResPaths { fs::path mainRoot; - std::vector> roots; + std::vector roots; public: ResPaths( fs::path mainRoot, - std::vector> roots + std::vector roots ); fs::path find(const std::string& filename) const; std::string findRaw(const std::string& filename) const; std::vector listdir(const std::string& folder) const; + std::vector listdirRaw(const std::string& folder) const; const fs::path& getMainRoot() const; }; diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index 9c6ebe97..7db2d5ab 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -140,6 +140,37 @@ static int l_file_write_bytes(lua_State* L) { } } +static int l_file_list_all_res(lua_State* L, const std::string& path) { + auto files = scripting::engine->getResPaths()->listdirRaw(path); + lua_createtable(L, files.size(), 0); + for (size_t i = 0; i < files.size(); i++) { + lua_pushstring(L, files[i].c_str()); + lua_rawseti(L, -2, i+1); + } + return 1; +} + +static int l_file_list(lua_State* L) { + std::string dirname = lua_tostring(L, 1); + if (dirname.find(':') == std::string::npos) { + return l_file_list_all_res(L, dirname); + } + fs::path path = resolve_path(L, dirname); + if (!fs::is_directory(path)) { + throw std::runtime_error(util::quote(path.u8string())+" is not a directory"); + } + lua_createtable(L, 0, 0); + size_t index = 1; + for (auto& entry : fs::directory_iterator(path)) { + auto name = entry.path().filename().u8string(); + auto file = dirname + "/" + name; + lua_pushstring(L, file.c_str()); + lua_rawseti(L, -2, index); + index++; + } + return 1; +} + const luaL_Reg filelib [] = { {"resolve", lua_wrap_errors}, {"find", lua_wrap_errors}, @@ -153,5 +184,6 @@ const luaL_Reg filelib [] = { {"mkdirs", lua_wrap_errors}, {"read_bytes", lua_wrap_errors}, {"write_bytes", lua_wrap_errors}, + {"list", lua_wrap_errors}, {NULL, NULL} }; From 94825f7b05f535f4a7e72c6984d59109df8e179a Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 14:39:43 +0300 Subject: [PATCH 2/6] added gui.get_mouse_pos function --- src/logic/scripting/lua/libgui.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 84973805..41e01994 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -16,6 +16,7 @@ #include "../../../graphics/ui/elements/Panel.hpp" #include "../../../graphics/ui/elements/Menu.hpp" #include "../../../graphics/ui/elements/InventoryView.hpp" +#include "../../../window/Events.hpp" #include "../../../frontend/UiDocument.hpp" #include "../../../frontend/locale.hpp" #include "../../../util/stringutil.hpp" @@ -459,8 +460,11 @@ static int l_gui_get_locales_info(lua_State* L) { } static int l_gui_getviewport(lua_State* L) { - lua::pushvec2_arr(L, scripting::engine->getGUI()->getContainer()->getSize()); - return 1; + return lua::pushvec2_arr(L, scripting::engine->getGUI()->getContainer()->getSize()); +} + +static int l_gui_get_mouse_pos(lua_State* L) { + return lua::pushvec2_arr(L, Events::cursor); } const luaL_Reg guilib [] = { @@ -470,6 +474,7 @@ const luaL_Reg guilib [] = { {"get_env", lua_wrap_errors}, {"str", lua_wrap_errors}, {"reindex", lua_wrap_errors}, + {"get_mouse_pos", lua_wrap_errors}, {"get_locales_info", lua_wrap_errors}, {NULL, NULL} }; From 8de986346ec8ab45be3e0875eea1381c9c28a0e6 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 16:30:30 +0300 Subject: [PATCH 3/6] get_mouse_pos moved to input library --- src/logic/scripting/lua/libgui.cpp | 6 ------ src/logic/scripting/lua/libinput.cpp | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index 41e01994..dca7b868 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -16,7 +16,6 @@ #include "../../../graphics/ui/elements/Panel.hpp" #include "../../../graphics/ui/elements/Menu.hpp" #include "../../../graphics/ui/elements/InventoryView.hpp" -#include "../../../window/Events.hpp" #include "../../../frontend/UiDocument.hpp" #include "../../../frontend/locale.hpp" #include "../../../util/stringutil.hpp" @@ -463,10 +462,6 @@ static int l_gui_getviewport(lua_State* L) { return lua::pushvec2_arr(L, scripting::engine->getGUI()->getContainer()->getSize()); } -static int l_gui_get_mouse_pos(lua_State* L) { - return lua::pushvec2_arr(L, Events::cursor); -} - const luaL_Reg guilib [] = { {"get_viewport", lua_wrap_errors}, {"getattr", lua_wrap_errors}, @@ -474,7 +469,6 @@ const luaL_Reg guilib [] = { {"get_env", lua_wrap_errors}, {"str", lua_wrap_errors}, {"reindex", lua_wrap_errors}, - {"get_mouse_pos", lua_wrap_errors}, {"get_locales_info", lua_wrap_errors}, {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libinput.cpp b/src/logic/scripting/lua/libinput.cpp index f654dc47..1c021093 100644 --- a/src/logic/scripting/lua/libinput.cpp +++ b/src/logic/scripting/lua/libinput.cpp @@ -1,4 +1,5 @@ #include "api_lua.hpp" +#include "lua_util.hpp" #include "lua_commons.hpp" #include "LuaState.hpp" #include "../scripting.hpp" @@ -39,9 +40,14 @@ static int l_add_callback(lua_State* L) { return 0; } +static int l_get_mouse_pos(lua_State* L) { + return lua::pushvec2_arr(L, Events::cursor); +} + const luaL_Reg inputlib [] = { {"keycode", lua_wrap_errors}, {"add_callback", lua_wrap_errors}, + {"get_mouse_pos", lua_wrap_errors}, {NULL, NULL} }; From 60cfe8595e3ad8d8e93b0d3c7b03ec7e43ff5a30 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 19:42:13 +0300 Subject: [PATCH 4/6] minor refactor --- src/frontend/screens/LevelScreen.cpp | 12 ++++++++---- src/frontend/screens/LevelScreen.hpp | 1 + src/window/Events.cpp | 5 ++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/frontend/screens/LevelScreen.cpp b/src/frontend/screens/LevelScreen.cpp index 94dc2239..7882d033 100644 --- a/src/frontend/screens/LevelScreen.cpp +++ b/src/frontend/screens/LevelScreen.cpp @@ -24,9 +24,9 @@ static debug::Logger logger("level-screen"); -LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) { - postProcessing = std::make_unique(); - +LevelScreen::LevelScreen(Engine* engine, Level* level) + : Screen(engine), postProcessing(std::make_unique()) +{ auto& settings = engine->getSettings(); auto assets = engine->getAssets(); auto menu = engine->getGUI()->getMenu(); @@ -48,7 +48,11 @@ LevelScreen::LevelScreen(Engine* engine, Level* level) : Screen(engine) { animator = std::make_unique(); animator->addAnimations(assets->getAnimations()); - auto content = level->content; + initializeContent(); +} + +void LevelScreen::initializeContent() { + auto content = controller->getLevel()->content; for (auto& entry : content->getPacks()) { auto pack = entry.second.get(); const ContentPack& info = pack->getInfo(); diff --git a/src/frontend/screens/LevelScreen.hpp b/src/frontend/screens/LevelScreen.hpp index ff41dd60..8f70cf12 100644 --- a/src/frontend/screens/LevelScreen.hpp +++ b/src/frontend/screens/LevelScreen.hpp @@ -26,6 +26,7 @@ class LevelScreen : public Screen { bool hudVisible = true; void updateHotkeys(); + void initializeContent(); public: LevelScreen(Engine* engine, Level* level); ~LevelScreen(); diff --git a/src/window/Events.cpp b/src/window/Events.cpp index 1232559e..8ac783fd 100644 --- a/src/window/Events.cpp +++ b/src/window/Events.cpp @@ -88,8 +88,7 @@ void Events::pollEvents() { binding.justChange = true; binding.onactived.notify(); } - } - else { + } else { if (binding.state) { binding.state = false; binding.justChange = true; @@ -107,7 +106,7 @@ void Events::bind(const std::string& name, inputtype type, mousecode code) { } void Events::bind(const std::string& name, inputtype type, int code) { - bindings[name] = Binding(type, code); + bindings.emplace(name, Binding(type, code)); } bool Events::active(const std::string& name) { From 1f3cf5ed53bb075c28750ebadb1f509f0a96907c Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 19:50:07 +0300 Subject: [PATCH 5/6] textbox editable property fix --- src/graphics/ui/elements/TextBox.cpp | 5 +++-- src/logic/scripting/lua/libgui.cpp | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/graphics/ui/elements/TextBox.cpp b/src/graphics/ui/elements/TextBox.cpp index 022a0732..e8f4cf48 100644 --- a/src/graphics/ui/elements/TextBox.cpp +++ b/src/graphics/ui/elements/TextBox.cpp @@ -130,7 +130,6 @@ void TextBox::drawBackground(const DrawContext* pctx, Assets*) { /// @brief Insert text at the caret. Also selected text will be erased /// @param text Inserting text void TextBox::paste(const std::wstring& text) { - eraseSelected(); if (caret >= input.length()) { input += text; @@ -203,7 +202,9 @@ void TextBox::setTextOffset(uint x) { } void TextBox::typed(unsigned int codepoint) { - paste(std::wstring({(wchar_t)codepoint})); + if (editable) { + paste(std::wstring({(wchar_t)codepoint})); + } } bool TextBox::validate() { diff --git a/src/logic/scripting/lua/libgui.cpp b/src/logic/scripting/lua/libgui.cpp index dca7b868..b8c30b6b 100644 --- a/src/logic/scripting/lua/libgui.cpp +++ b/src/logic/scripting/lua/libgui.cpp @@ -204,6 +204,13 @@ static int p_get_text(UINode* node) { return 0; } +static int p_get_editable(UINode* node) { + if (auto box = dynamic_cast(node)) { + return state->pushboolean(box->isEditable()); + } + return 0; +} + static int p_get_add(UINode* node) { if (dynamic_cast(node)) { return state->pushcfunction(l_container_add); @@ -268,6 +275,7 @@ static int l_gui_getattr(lua_State* L) { {"placeholder", p_get_placeholder}, {"valid", p_is_valid}, {"text", p_get_text}, + {"editable", p_get_editable}, {"value", p_get_value}, {"min", p_get_min}, {"max", p_get_max}, @@ -325,6 +333,11 @@ static void p_set_text(UINode* node, int idx) { box->setText(util::str2wstr_utf8(state->tostring(idx))); } } +static void p_set_editable(UINode* node, int idx) { + if (auto box = dynamic_cast(node)) { + box->setEditable(state->toboolean(idx)); + } +} static void p_set_value(UINode* node, int idx) { if (auto bar = dynamic_cast(node)) { bar->setValue(state->tonumber(idx)); @@ -397,6 +410,7 @@ static int l_gui_setattr(lua_State* L) { {"enabled", p_set_enabled}, {"placeholder", p_set_placeholder}, {"text", p_set_text}, + {"editable", p_set_editable}, {"value", p_set_value}, {"min", p_set_min}, {"max", p_set_max}, From 8054d4ba55852a1665ad3b9e9a629f42859e743f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 12 May 2024 19:56:38 +0300 Subject: [PATCH 6/6] file.readlines --- res/scripts/stdlib.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index dcc7f382..877d38a4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -276,6 +276,15 @@ function table.tostring(t) return s..']' end +function file.readlines(path) + local str = file.read(path) + local lines = {} + for s in str:gmatch("[^\r\n]+") do + table.insert(lines, s) + end + return lines +end + -- Deprecated functions block_index = block.index block_name = block.name