From ac20676b3a0873f7e16b148c36100a06b8e2984b Mon Sep 17 00:00:00 2001 From: ChancellorIkseew <156004311+ChancellorIkseew@users.noreply.github.com> Date: Tue, 6 May 2025 03:30:50 +1000 Subject: [PATCH 01/13] add weather.list command (#526) --- res/scripts/stdcmd.lua | 13 +++++++++++++ src/logic/scripting/lua/libs/libfile.cpp | 7 ++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/res/scripts/stdcmd.lua b/res/scripts/stdcmd.lua index c06f059a..0308910f 100644 --- a/res/scripts/stdcmd.lua +++ b/res/scripts/stdcmd.lua @@ -291,6 +291,19 @@ console.add_command( end ) +console.add_command( + "weather.list", + "Show available weather presets list", + function(args, kwargs) + local filenames = file.list_all_res("presets/weather/") + local presets = " " + for index, filename in pairs(filenames) do + presets = presets .. "\n" .. file.stem(filename) + end + return "available presets:" .. presets + end +) + console.cheats = { "blocks.fill", "tp", diff --git a/src/logic/scripting/lua/libs/libfile.cpp b/src/logic/scripting/lua/libs/libfile.cpp index fa2b2954..717ff52b 100644 --- a/src/logic/scripting/lua/libs/libfile.cpp +++ b/src/logic/scripting/lua/libs/libfile.cpp @@ -1,4 +1,3 @@ -#include #include #include @@ -156,7 +155,8 @@ static int l_write_bytes(lua::State* L) { return lua::pushboolean(L, res); } -static int l_list_all_res(lua::State* L, const std::string& path) { +static int l_list_all_res(lua::State* L) { + std::string path = lua::require_string(L, 1); auto files = engine->getResPaths().listdirRaw(path); lua::createtable(L, files.size(), 0); for (size_t i = 0; i < files.size(); i++) { @@ -169,7 +169,7 @@ static int l_list_all_res(lua::State* L, const std::string& path) { static int l_list(lua::State* L) { std::string dirname = lua::require_string(L, 1); if (dirname.find(':') == std::string::npos) { - return l_list_all_res(L, dirname); + return l_list_all_res(L); } io::path path = dirname; if (!io::is_directory(path)) { @@ -265,6 +265,7 @@ const luaL_Reg filelib[] = { {"isfile", lua::wrap}, {"length", lua::wrap}, {"list", lua::wrap}, + {"list_all_res", lua::wrap}, {"mkdir", lua::wrap}, {"mkdirs", lua::wrap}, {"read_bytes", lua::wrap}, From 231c0bce7ef6835de003fe8a266b0acf4d80e806 Mon Sep 17 00:00:00 2001 From: Usow Maxim Date: Mon, 12 May 2025 08:11:29 +0700 Subject: [PATCH 02/13] Can build with docker on Windows --- Dockerfile | 10 ++++++++++ README.md | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/Dockerfile b/Dockerfile index f52496de..9d0005f5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ g++ \ make \ cmake \ + pkg-config \ xauth \ gdb \ gdbserver \ @@ -25,8 +26,17 @@ RUN apt-get update && apt-get install --no-install-recommends -y \ libvorbis-dev \ libcurl4-openssl-dev \ ca-certificates \ + wget \ && rm -rf /var/lib/apt/lists/* +# Установка CMake >= 3.26 вручную +ARG CMAKE_VERSION=3.27.9 +RUN wget https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.sh && \ + chmod +x cmake-${CMAKE_VERSION}-linux-x86_64.sh && \ + ./cmake-${CMAKE_VERSION}-linux-x86_64.sh --skip-license --prefix=/usr/local && \ + rm cmake-${CMAKE_VERSION}-linux-x86_64.sh + + # Install EnTT RUN git clone https://github.com/skypjack/entt.git && \ cd entt/build && \ diff --git a/README.md b/README.md index 91318051..832ac43f 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,8 @@ cmake --build --preset default-vs-msvc-windows See +### Do you have Linux + ### Step 1. Build docker container ```sh @@ -157,3 +159,31 @@ docker run --rm -it -v$(pwd):/project voxel-engine bash -c "cmake -DCMAKE_BUILD_ ```sh docker run --rm -it -v$(pwd):/project -v/tmp/.X11-unix:/tmp/.X11-unix -v${XAUTHORITY}:/home/user/.Xauthority:ro -eDISPLAY --network=host voxel-engine ./build/VoxelEngine ``` + +### Do you have Windows + +### Step 1. You need to install VcXsrv + +### Step 2. Run VcXsrv with the command + +```powershell +.\vcxsrv.exe :0 -multiwindow -ac +``` + +### Step 3. Build docker container + +```powershell +docker build -t voxel-engine . +``` + +### Step 4. Build project using the docker container + +```powershell +docker run --rm -it -v "${PWD}:/project" voxel-engine bash -c "cmake -DCMAKE_BUILD_TYPE=Release -Bbuild && cmake --build build" +``` + +### Step 5. Run project using the docker container + +```powershell +docker run --rm -it -v "${PWD}:/project" -e DISPLAY=host.docker.internal:0.0 --network host voxel-engine ./build/VoxelEngine +``` \ No newline at end of file From 9c28313d2447d42bf2d7c95ff482446c541eb03e Mon Sep 17 00:00:00 2001 From: Rost Alexeev <148265518+R0STUS@users.noreply.github.com> Date: Tue, 20 May 2025 16:46:10 +0200 Subject: [PATCH 03/13] Readme engine name fix VoxelEngine-Cpp -> VoxelCore --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 832ac43f..18ad6c49 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ ## Latest release -- [Download](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelEngine-Cpp/releases/latest) -- [Documentation](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.27/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelEngine-Cpp/blob/release-0.27/doc/ru/main-page.md) +- [Download](https://github.com/MihailRis/VoxelCore/releases/latest) | [Скачать](https://github.com/MihailRis/VoxelCore/releases/latest) +- [Documentation](https://github.com/MihailRis/VoxelCore/blob/release-0.27/doc/en/main-page.md) | [Документация](https://github.com/MihailRis/VoxelCore/blob/release-0.27/doc/ru/main-page.md) ## Build project in Linux @@ -71,8 +71,8 @@ yay -S entt ### Building engine with CMake ```sh -git clone --recursive https://github.com/MihailRis/VoxelEngine-Cpp.git -cd VoxelEngine-Cpp +git clone --recursive https://github.com/MihailRis/VoxelCore.git +cd VoxelCore mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release .. @@ -95,8 +95,8 @@ brew install glfw3 glew glm libpng libvorbis lua luajit libcurl openal-soft skyp ### Building engine with CMake ```sh -git clone --recursive https://github.com/MihailRis/VoxelEngine-Cpp.git -cd VoxelEngine-Cpp +git clone --recursive https://github.com/MihailRis/VoxelCore.git +cd VoxelCore mkdir build cd build cmake -DCMAKE_BUILD_TYPE=Release .. @@ -128,8 +128,8 @@ $env:PATH = "$env:VCPKG_ROOT;$env:PATH" After installing **vcpkg** you can build project: ```PowerShell -git clone --recursive https://github.com/MihailRis/VoxelEngine-Cpp.git -cd VoxelEngine-Cpp +git clone --recursive https://github.com/MihailRis/VoxelCore.git +cd VoxelCore cmake --preset default-vs-msvc-windows cmake --build --preset default-vs-msvc-windows ``` @@ -186,4 +186,4 @@ docker run --rm -it -v "${PWD}:/project" voxel-engine bash -c "cmake -DCMAKE_BUI ```powershell docker run --rm -it -v "${PWD}:/project" -e DISPLAY=host.docker.internal:0.0 --network host voxel-engine ./build/VoxelEngine -``` \ No newline at end of file +``` From 0a413ccc236bb19b7e3918731a2579241576d2d3 Mon Sep 17 00:00:00 2001 From: rekvizitt <58174945+rekvizitt@users.noreply.github.com> Date: Wed, 21 May 2025 09:41:31 +0300 Subject: [PATCH 04/13] Update be_BY.txt --- res/texts/be_BY.txt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/res/texts/be_BY.txt b/res/texts/be_BY.txt index 624e2028..879e5a35 100644 --- a/res/texts/be_BY.txt +++ b/res/texts/be_BY.txt @@ -19,8 +19,17 @@ Problems=Праблемы Monitor=Маніторынг Debug=Адладка File=Файл +Read only=Толькі для чытання +Save=Захаваць +Grant %{0} pack modification permission?=Выдаць дазвол на мадыфікацыю пака %{0}? +Error at line %{0}=Памылка ў радку %{0} +Run=Запусціць +Filter=Фільтр +editor.info.tooltip=CTRL+S - Захаваць\nCTRL+R - Запусціць\nCTRL+Z - Скасаваць\nCTRL+Y - Паўтарыць devtools.traceback=Стэк выклікаў (ад апошняга) +devtools.output=Вывод + error.pack-not-found=Не ўдалося знайсці пакет error.dependency-not-found=Выкарыстоўваная залежнасць не знойдзена pack.remove-confirm=Выдаліць увесь кантэнт, які пастаўляецца пакетам/пакетамі, са свету (беззваротна)? @@ -43,7 +52,7 @@ menu.Display=Дысплей menu.Graphics=Графіка menu.missing-content=Адсутнічае Кантэнт! menu.New World=Новы Свет -menu.Open worlds folder=Адкрыць папку з сусветамі +menu.Open worlds folder=Адкрыць тэчку са сусветамі menu.Worlds=Сусветы menu.Page not found=Старонка не знойдзена menu.Quit=Выхад @@ -51,8 +60,8 @@ menu.Save and Quit to Menu=Захаваць і Выйсці ў Меню menu.Settings=Налады menu.Reset settings=Скінуць налады menu.Contents Menu=Меню кантэнт-пакаў -menu.Open data folder=Адкрыць папку з дадзенымі -menu.Open content folder=Адкрыць папку [content] +menu.Open data folder=Адкрыць тэчку з дадзенымі +menu.Open content folder=Адкрыць тэчку [content] world.Seed=Зерне world.Name=Назва @@ -112,4 +121,4 @@ player.fast_interaction=Паскоранае ўзаемадзеянне player.flight=Палёт player.drop=Выкінуць прадмет camera.zoom=Прыбліжэнне -camera.mode=Змяніць рэжым камеры \ No newline at end of file +camera.mode=Змяніць рэжым камеры From 019c93d524c265ee1442063f298496dfd229fc4f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 17:08:01 +0300 Subject: [PATCH 05/13] add 'refresh' containers method --- src/logic/scripting/lua/libs/libgui.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 68327c8e..89c778c3 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -114,6 +114,16 @@ static int l_node_destruct(lua::State* L) { return 0; } +static int l_container_refresh(lua::State* L) { + auto docnode = get_document_node(L); + auto node = dynamic_cast(docnode.node.get()); + if (node == nullptr) { + return 0; + } + node->refresh(); + return 0; +} + static int l_node_reposition(lua::State* L) { auto docnode = get_document_node(L); docnode.node->reposition(); @@ -408,6 +418,13 @@ static int p_get_destruct(UINode*, lua::State* L) { return lua::pushcfunction(L, lua::wrap); } +static int p_refresh(UINode* node, lua::State* L) { + if (dynamic_cast(node)) { + return lua::pushcfunction(L, lua::wrap); + } + return 0; +} + static int p_get_reposition(UINode*, lua::State* L) { return lua::pushcfunction(L, lua::wrap); } @@ -539,6 +556,7 @@ static int l_gui_getattr(lua::State* L) { {"moveInto", p_move_into}, {"add", p_get_add}, {"destruct", p_get_destruct}, + {"refresh", p_refresh}, {"reposition", p_get_reposition}, {"clear", p_get_clear}, {"setInterval", p_set_interval}, From 8f342fe429bcb4da5eb1ea8ed7aebd8803b2a7ea Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 17:15:12 +0300 Subject: [PATCH 06/13] add util::stack_vector --- src/util/stack_vector.hpp | 99 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/util/stack_vector.hpp diff --git a/src/util/stack_vector.hpp b/src/util/stack_vector.hpp new file mode 100644 index 00000000..e73bbb11 --- /dev/null +++ b/src/util/stack_vector.hpp @@ -0,0 +1,99 @@ +#pragma once + +namespace util { + template + class stack_vector { + public: + stack_vector() : size_(0) {} + + stack_vector(const stack_vector& other) + : size_(other.size_) { + for (int i = 0; i < size_; ++i) { + new (&data_[i]) T(data_[i]); + } + } + + stack_vector(stack_vector&& other) noexcept + : size_(other.size_) { + for (int i = 0; i < size_; ++i) { + new (&data_[i]) T(std::move(other.data_[i])); + } + other.size_ = 0; + } + + stack_vector(const std::initializer_list& init) : size_(0) { + static_assert( + init.size() <= capacity, + "initializer list exceeds stack vector capacity" + ); + for (const auto& value : init) { + new (&data_[size_++]) T(value); + } + } + + ~stack_vector() { + clear(); + } + + void push_back(const T& value) { + if (size_ < capacity) { + data_[size_++] = value; + } else { + throw std::overflow_error("stack vector capacity exceeded"); + } + } + + void pop_back() { + if (size_ > 0) { + data_[size_ - 1].~T(); + --size_; + } else { + throw std::underflow_error("stack vector is empty"); + } + } + + void clear() { + for (int i = 0; i < size_; ++i) { + data_[i].~T(); + } + size_ = 0; + } + + T& operator[](int index) { + return data_[index]; + } + + const T& operator[](int index) const { + return data_[index]; + } + + T& at(int index) { + if (index < 0 || index >= size_) { + throw std::out_of_range("index out of range"); + } + return data_[index]; + } + + const T& at(int index) const { + if (index < 0 || index >= size_) { + throw std::out_of_range("index out of range"); + } + return data_[index]; + } + + int size() const { + return size_; + } + + bool empty() const { + return size_ == 0; + } + + bool full() const { + return size_ == capacity; + } + private: + T data_[capacity]; + int size_; + }; +} From 4333d9ab061a64abc70b104ffd07b476fb318cf8 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 23:08:59 +0300 Subject: [PATCH 07/13] feat: support alternative vcm models syntax --- res/devtools/syntax/vcm.toml | 3 + res/models/stairs.vcm | 4 ++ res/models/stairs.xml | 6 -- res/modules/internal/scripts_registry.lua | 2 +- src/assets/assetload_funcs.cpp | 40 +++++++---- src/coders/vcm.cpp | 21 ++++-- src/coders/xml.cpp | 77 ++++++++++++++++++++++ src/coders/xml.hpp | 4 ++ src/logic/scripting/lua/libs/libassets.cpp | 2 +- test/coders/xml.cpp | 24 +++++++ 10 files changed, 155 insertions(+), 28 deletions(-) create mode 100644 res/devtools/syntax/vcm.toml create mode 100644 res/models/stairs.vcm delete mode 100644 res/models/stairs.xml create mode 100644 test/coders/xml.cpp diff --git a/res/devtools/syntax/vcm.toml b/res/devtools/syntax/vcm.toml new file mode 100644 index 00000000..ca05b6a1 --- /dev/null +++ b/res/devtools/syntax/vcm.toml @@ -0,0 +1,3 @@ +language = "VCM" +extensions = ["vcm"] +line-comment-start = "#" diff --git a/res/models/stairs.vcm b/res/models/stairs.vcm new file mode 100644 index 00000000..2027c09e --- /dev/null +++ b/res/models/stairs.vcm @@ -0,0 +1,4 @@ +@box from (0,0,0) to (1,0.5,1) delete (top,south) +@box from (0,0.5,0) to (1,1,0.5) delete (bottom,south) +@rect from (0,0.5,0.5) right (1,0,0) up (0,0,0.5) texture "$2" +@rect from (0,0,0) right (1,0,0) up (0,1,0) texture "$1" diff --git a/res/models/stairs.xml b/res/models/stairs.xml deleted file mode 100644 index 5921e08c..00000000 --- a/res/models/stairs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/res/modules/internal/scripts_registry.lua b/res/modules/internal/scripts_registry.lua index db6fc321..ef347159 100644 --- a/res/modules/internal/scripts_registry.lua +++ b/res/modules/internal/scripts_registry.lua @@ -55,7 +55,7 @@ local function load_models_list(packs) local registry = export.registry for _, filename in ipairs(file.list("models")) do local ext = file.ext(filename) - if ext == "xml" then + if ext == "xml" or ext == "vcm" then registry[filename] = {type="model", unit=file.stem(filename)} table.insert(export.filenames, filename) end diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index af8fb3c9..d5994469 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -352,21 +352,35 @@ assetload::postfunc assetload::model( throw; } } - path = paths.find(file + ".xml"); - if (io::exists(path)) { - auto text = io::read_string(path); - try { - auto model = vcm::parse(path.string(), text).release(); - return [=](Assets* assets) { - request_textures(loader, *model); - assets->store(std::unique_ptr(model), name); - }; - } catch (const parsing_error& err) { - std::cerr << err.errorLog() << std::endl; - throw; + + std::array extensions { + ".xml", + ".vcm" + }; + + path = ""; + for (const auto& ext : extensions) { + auto newPath = paths.find(file + ext); + if (io::exists(newPath)) { + path = std::move(newPath); + break; } } - throw std::runtime_error("could not to find model " + util::quote(file)); + if (path.empty()) { + throw std::runtime_error("could not to find model " + util::quote(file)); + } + + auto text = io::read_string(path); + try { + auto model = vcm::parse(path.string(), text).release(); + return [=](Assets* assets) { + request_textures(loader, *model); + assets->store(std::unique_ptr(model), name); + }; + } catch (const parsing_error& err) { + std::cerr << err.errorLog() << std::endl; + throw; + } } static void read_anim_file( diff --git a/src/coders/vcm.cpp b/src/coders/vcm.cpp index e86fc138..20c50982 100644 --- a/src/coders/vcm.cpp +++ b/src/coders/vcm.cpp @@ -5,6 +5,7 @@ #include "xml.hpp" #include "util/stringutil.hpp" #include "graphics/commons/Model.hpp" +#include "io/io.hpp" using namespace vcm; using namespace xml; @@ -143,12 +144,18 @@ static std::unique_ptr load_model(const xmlelement& root) { std::unique_ptr vcm::parse( std::string_view file, std::string_view src ) { - auto doc = xml::parse(file, src); - const auto& root = *doc->getRoot(); - if (root.getTag() != "model") { - throw std::runtime_error( - "'model' tag expected as root, got '" + root.getTag() + "'" - ); + try { + auto doc = io::path(std::string(file)).extension() == ".xml" + ? xml::parse(file, src) : xml::parse_vcm(file, src, "model"); + const auto& root = *doc->getRoot(); + if (root.getTag() != "model") { + throw std::runtime_error( + "'model' tag expected as root, got '" + root.getTag() + "'" + ); + } + std::cout << xml::stringify(*doc) << std::endl; + return load_model(root); + } catch (const parsing_error& err) { + throw std::runtime_error(err.errorLog()); } - return load_model(root); } diff --git a/src/coders/xml.cpp b/src/coders/xml.cpp index 9ed51e0c..0763fa43 100644 --- a/src/coders/xml.cpp +++ b/src/coders/xml.cpp @@ -355,6 +355,83 @@ std::unique_ptr xml::parse( return parser.parse(); } +namespace { +class VcmParser : public BasicParser { +public: + VcmParser(std::string_view filename, std::string_view source) + : BasicParser(filename, source) { + document = std::make_unique("1.0", "UTF-8"); + hashComment = true; + } + + std::string parseValue() { + char c = peek(); + if (c == '"' || c == '\'') { + nextChar(); + return parseString(c); + } + if (c == '(') { + nextChar(); + // TODO: replace with array parsing after moving to dv::value's + std::string value = std::string(readUntil(')')); + expect(')'); + return value; + } + return std::string(readUntilWhitespace()); + } + + void parseSubElements(Node& node) { + skipWhitespace(); + while (hasNext()) { + if (peek() != '@') { + throw error("unexpected character in element"); + } + nextChar(); + auto subnodePtr = std::make_unique(parseName()); + auto subnode = subnodePtr.get(); + node.add(std::move(subnodePtr)); + + skipWhitespace(); + while (hasNext() && peek() != '@' && peek() != '{' && peek() != '}') { + std::string attrname = parseName(); + skipWhitespace(); + std::string value = parseValue(); + subnode->set(attrname, value); + skipWhitespace(); + } + if (!hasNext()) { + break; + } + char c = peek(); + if (c == '{') { + nextChar(); + parseSubElements(*subnode); + expect('}'); + skipWhitespace(); + } else if (c == '}') { + break; + } + } + } + + std::unique_ptr parse(const std::string& rootTag) { + auto root = std::make_unique(rootTag); + parseSubElements(*root); + document->setRoot(std::move(root)); + return std::move(document); + } +private: + std::unique_ptr document; +}; +} + +std::unique_ptr xml::parse_vcm( + std::string_view filename, std::string_view source, std::string_view tag +) { + VcmParser parser(filename, source); + return parser.parse(std::string(tag)); +} + inline void newline( std::stringstream& ss, bool nice, const std::string& indentStr, int indent ) { diff --git a/src/coders/xml.hpp b/src/coders/xml.hpp index f626dd34..24cf0fbd 100644 --- a/src/coders/xml.hpp +++ b/src/coders/xml.hpp @@ -126,5 +126,9 @@ namespace xml { std::string_view filename, std::string_view source ); + std::unique_ptr parse_vcm( + std::string_view filename, std::string_view source, std::string_view tag + ); + using xmlelement = Node; } diff --git a/src/logic/scripting/lua/libs/libassets.cpp b/src/logic/scripting/lua/libs/libassets.cpp index 1e0d6f20..8cfb8ca8 100644 --- a/src/logic/scripting/lua/libs/libassets.cpp +++ b/src/logic/scripting/lua/libs/libassets.cpp @@ -51,7 +51,7 @@ static int l_parse_model(lua::State* L) { auto string = lua::require_lstring(L, 2); auto name = lua::require_string(L, 3); - if (format == "xml") { + if (format == "xml" || format == "vcm") { engine->getAssets()->store(vcm::parse(name, string), name); } else { throw std::runtime_error("unknown format " + util::quote(std::string(format))); diff --git a/test/coders/xml.cpp b/test/coders/xml.cpp new file mode 100644 index 00000000..1357a449 --- /dev/null +++ b/test/coders/xml.cpp @@ -0,0 +1,24 @@ +#include + +#include "coders/xml.hpp" +#include "coders/commons.hpp" + +TEST(XML, VCM) { + std::string code = "" + "@line x1 y1 z1\n" + "# @tst ysfdrg\n" + "@box {\n" + " @rect texture \"$2\"\n" + " @utro a 53.1\n" + "}\n" + ; + std::cout << code << std::endl; + + try { + auto document = xml::parse_vcm("", code, "test"); + std::cout << xml::stringify(*document); + } catch (const parsing_error& err) { + std::cerr << err.errorLog() << std::endl; + throw err; + } +} From 4ff42b94c34221d07538325ea97b3e1aebafb468 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 23:09:59 +0300 Subject: [PATCH 08/13] update editor & rename 'model' property to 'src' --- res/layouts/code_editor.xml | 82 +++++++++++++++++---------------- res/layouts/code_editor.xml.lua | 41 +++++++++++++++-- res/layouts/console.xml | 3 +- res/layouts/console.xml.lua | 2 + src/graphics/ui/gui_xml.cpp | 2 +- src/io/engine_paths.cpp | 3 ++ 6 files changed, 86 insertions(+), 47 deletions(-) diff --git a/res/layouts/code_editor.xml b/res/layouts/code_editor.xml index 02881b44..4b61c4d8 100644 --- a/res/layouts/code_editor.xml +++ b/res/layouts/code_editor.xml @@ -8,47 +8,49 @@ - - - - - - - - - + + + + + + + + + + + + - - - + + diff --git a/res/layouts/code_editor.xml.lua b/res/layouts/code_editor.xml.lua index 55250c13..de460f2e 100644 --- a/res/layouts/code_editor.xml.lua +++ b/res/layouts/code_editor.xml.lua @@ -104,10 +104,29 @@ function unlock_access() ) end +local function reload_model(filename, name) + assets.parse_model("xml", document.editor.text, name) +end + function run_current_file() if not current_file.filename then return end + + local info = registry.get_info(current_file.filename) + local script_type = info and info.type or "file" + local unit = info and info.unit + + if script_type == "model" then + print(current_file.filename) + clear_output() + local _, err = pcall(reload_model, current_file.filename, unit) + if err then + document.output:paste(string.format("\n[#FF0000]%s[#FFFFFF]", err)) + end + return + end + local chunk, err = loadstring(document.editor.text, current_file.filename) clear_output() if not chunk then @@ -119,9 +138,7 @@ function run_current_file() ) return end - local info = registry.get_info(current_file.filename) - local script_type = info and info.type or "file" - local unit = info and info.unit + save_current_file() local func = function() @@ -191,6 +208,7 @@ events.on("core:open_traceback", function(traceback_b64) tb_list.size = srcsize end) +--- Save the current file in the code editor if has writeable path. function save_current_file() if not current_file.mutable then return @@ -202,7 +220,22 @@ function save_current_file() document.editor.edited = false end +--- Open a file in the code editor. +--- @param filename string - the path to the file to open. +--- @param line integer - the line number to focus on (optional). +--- @param mutable string - writeable file path (optional). function open_file_in_editor(filename, line, mutable) + debug.log("opening file " .. string.escape(filename) .. " in editor") + + local ext = file.ext(filename) + if ext == "xml" or ext == "vcm" then + document.modelviewer.src = file.stem(filename) + document.modelviewer.visible = true + else + document.modelviewer.visible = false + end + document.codePanel:refresh() + local editor = document.editor local source = file.read(filename):gsub('\t', ' ') editor.scroll = 0 @@ -225,7 +258,7 @@ end function on_open(mode) registry = require "core:internal/scripts_registry" - document.editorContainer:setInterval(200, refresh_file_title) + document.codePanel:setInterval(200, refresh_file_title) clear_traceback() clear_output() diff --git a/res/layouts/console.xml b/res/layouts/console.xml index 16fbbb0b..3772d240 100644 --- a/res/layouts/console.xml +++ b/res/layouts/console.xml @@ -22,8 +22,7 @@ markup="md" > - read_split_box( static std::shared_ptr read_model_viewer( UiXmlReader& reader, const xml::xmlelement& element ) { - auto model = element.attr("model", "").getText(); + auto model = element.attr("src", "").getText(); auto viewer = std::make_shared( reader.getGUI(), glm::vec2(), model ); diff --git a/src/io/engine_paths.cpp b/src/io/engine_paths.cpp index cb2d11e9..39851228 100644 --- a/src/io/engine_paths.cpp +++ b/src/io/engine_paths.cpp @@ -192,6 +192,9 @@ std::string EnginePaths::createWriteableDevice(const std::string& name) { break; } } + if (name == "core") { + folder = "res:"; + } if (folder.emptyOrInvalid()) { throw std::runtime_error("pack not found"); } From 476865504bf3328426c311f3b4ba97aa535d1cbc Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 23:10:31 +0300 Subject: [PATCH 09/13] add 'src' scripting property to modelviewer --- src/logic/scripting/lua/libs/libgui.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/logic/scripting/lua/libs/libgui.cpp b/src/logic/scripting/lua/libs/libgui.cpp index 89c778c3..8a1f12db 100644 --- a/src/logic/scripting/lua/libs/libgui.cpp +++ b/src/logic/scripting/lua/libs/libgui.cpp @@ -14,6 +14,7 @@ #include "graphics/ui/elements/TextBox.hpp" #include "graphics/ui/elements/TrackBar.hpp" #include "graphics/ui/elements/InlineFrame.hpp" +#include "graphics/ui/elements/ModelViewer.hpp" #include "graphics/ui/gui_util.hpp" #include "graphics/ui/markdown.hpp" #include "graphics/core/Font.hpp" @@ -351,6 +352,8 @@ static int p_get_src(UINode* node, lua::State* L) { return lua::pushstring(L, image->getTexture()); } else if (auto iframe = dynamic_cast(node)) { return lua::pushstring(L, iframe->getSrc()); + } else if (auto modelviewer = dynamic_cast(node)) { + return lua::pushstring(L, modelviewer->getModel()); } return 0; } @@ -693,6 +696,8 @@ static void p_set_src(UINode* node, lua::State* L, int idx) { image->setTexture(lua::require_string(L, idx)); } else if (auto iframe = dynamic_cast(node)) { iframe->setSrc(lua::require_string(L, idx)); + } else if (auto modelviewer = dynamic_cast(node)) { + modelviewer->setModel(lua::require_string(L, idx)); } } static void p_set_region(UINode* node, lua::State* L, int idx) { From 634a56a3557f85e6b377f5587e9d4be14fca1668 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 1 Jun 2025 23:10:56 +0300 Subject: [PATCH 10/13] update splitbox refresh method --- src/graphics/ui/elements/SplitBox.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/graphics/ui/elements/SplitBox.cpp b/src/graphics/ui/elements/SplitBox.cpp index 8cbc94bf..c1fbcbcc 100644 --- a/src/graphics/ui/elements/SplitBox.cpp +++ b/src/graphics/ui/elements/SplitBox.cpp @@ -1,5 +1,7 @@ #include "SplitBox.hpp" +#include "util/stack_vector.hpp" + using namespace gui; SplitBox::SplitBox(GUI& gui, const glm::vec2& size, float splitPos, Orientation orientation) @@ -28,18 +30,31 @@ void SplitBox::mouseMove(int x, int y) { void SplitBox::refresh() { Container::refresh(); - if (nodes.empty()) { + util::stack_vector visibleNodes; + + for (const auto& node : nodes) { + if (!node->isVisible()) { + continue; + } + visibleNodes.push_back(node.get()); + if (visibleNodes.full()) { + break; + } + } + + if (visibleNodes.empty()) { return; } + glm::vec2 size = getSize(); - if (nodes.size() == 1) { - auto node = nodes.at(0); + if (visibleNodes.size() == 1) { + auto node = visibleNodes.at(0); node->setPos(glm::vec2()); node->setSize(size); return; } - auto nodeA = nodes.at(0); - auto nodeB = nodes.at(1); + auto nodeA = visibleNodes.at(0); + auto nodeB = visibleNodes.at(1); float sepRadius = interval / 2.0f; From 67a517e03e06339bde93c7b4ab7bb940d55f28a9 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 2 Jun 2025 21:03:38 +0300 Subject: [PATCH 11/13] fix missing include --- src/logic/scripting/lua/libs/libcore.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/logic/scripting/lua/libs/libcore.cpp b/src/logic/scripting/lua/libs/libcore.cpp index 4f4c46cd..c453927c 100644 --- a/src/logic/scripting/lua/libs/libcore.cpp +++ b/src/logic/scripting/lua/libs/libcore.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "api_lua.hpp" #include "constants.hpp" From 9c7bd05a749880d127661f4a4f332209ea0ac523 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 2 Jun 2025 21:14:23 +0300 Subject: [PATCH 12/13] fix windows build --- src/assets/assetload_funcs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/assets/assetload_funcs.cpp b/src/assets/assetload_funcs.cpp index d5994469..db77e354 100644 --- a/src/assets/assetload_funcs.cpp +++ b/src/assets/assetload_funcs.cpp @@ -1,5 +1,6 @@ #include "assetload_funcs.hpp" +#include #include #include #include From 96b760754eedf58c55f415b5d0c18b94da1ec431 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 2 Jun 2025 21:24:49 +0300 Subject: [PATCH 13/13] fix windows build --- src/graphics/ui/elements/ModelViewer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/graphics/ui/elements/ModelViewer.cpp b/src/graphics/ui/elements/ModelViewer.cpp index 686a6a01..acc8170c 100644 --- a/src/graphics/ui/elements/ModelViewer.cpp +++ b/src/graphics/ui/elements/ModelViewer.cpp @@ -1,3 +1,4 @@ +#include #include #include "ModelViewer.hpp"