From e590d06bb0afac1537289426be6785f540002872 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 30 Sep 2024 01:55:42 +0300 Subject: [PATCH] add file.read_combined_list(...) --- src/engine.cpp | 23 +++++++++++++++-------- src/files/engine_paths.cpp | 28 ++++++++++++++++++++++++++++ src/files/engine_paths.hpp | 6 ++++++ src/files/files.hpp | 5 +++++ src/logic/scripting/lua/libfile.cpp | 9 +++++++++ 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/src/engine.cpp b/src/engine.cpp index 7bb847d9..538721ea 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -303,21 +303,28 @@ void Engine::loadContent() { names = manager.assembly(names); contentPacks = manager.getAll(names); - std::vector resRoots; - { - auto pack = ContentPack::createCore(paths); - resRoots.push_back({"core", pack.folder}); - ContentLoader(&pack, contentBuilder).load(); - load_configs(pack.folder); - } + auto corePack = ContentPack::createCore(paths); + + // Setup filesystem entry points + std::vector resRoots { + {"core", corePack.folder} + }; for (auto& pack : contentPacks) { resRoots.push_back({pack.id, pack.folder}); + } + resPaths = std::make_unique(resdir, resRoots); + + // Load content + { + ContentLoader(&corePack, contentBuilder).load(); + load_configs(corePack.folder); + } + for (auto& pack : contentPacks) { ContentLoader(&pack, contentBuilder).load(); load_configs(pack.folder); } content = contentBuilder.build(); - resPaths = std::make_unique(resdir, resRoots); langs::setup(resdir, langs::current->getId(), contentPacks); loadAssets(); diff --git a/src/files/engine_paths.cpp b/src/files/engine_paths.cpp index d665603e..c3b9585e 100644 --- a/src/files/engine_paths.cpp +++ b/src/files/engine_paths.cpp @@ -10,6 +10,9 @@ #include #include "WorldFiles.hpp" +#include "debug/Logger.hpp" + +static debug::Logger logger("engine-paths"); /// @brief ENUM for accessing folder and file names @@ -258,6 +261,31 @@ std::vector ResPaths::listdir( return entries; } +dv::value ResPaths::readCombinedList(const std::string& filename) { + dv::value list = dv::list(); + for (const auto& root : roots) { + auto path = root.path / fs::u8path(filename); + if (!fs::exists(path)) { + continue; + } + try { + auto value = files::read_object(path); + if (!value.isList()) { + logger.warning() << "reading combined list " << root.name << ":" + << filename << " is not a list (skipped)"; + continue; + } + for (const auto& elem : value) { + list.add(elem); + } + } catch (const std::runtime_error& err) { + logger.warning() << "reading combined list " << root.name << ":" + << filename << ": " << err.what(); + } + } + return list; +} + const std::filesystem::path& ResPaths::getMainRoot() const { return mainRoot; } diff --git a/src/files/engine_paths.hpp b/src/files/engine_paths.hpp index ceb2f613..d9af69a3 100644 --- a/src/files/engine_paths.hpp +++ b/src/files/engine_paths.hpp @@ -6,6 +6,7 @@ #include #include +#include "data/dv.hpp" #include "content/ContentPack.hpp" @@ -63,6 +64,11 @@ public: std::vector listdir(const std::string& folder) const; std::vector listdirRaw(const std::string& folder) const; + /// @brief Read all found list versions from all packs and combine into a + /// single list. Invalid versions will be skipped with logging a warning + /// @param file *.json file path relative to entry point + dv::value readCombinedList(const std::string& file); + const std::filesystem::path& getMainRoot() const; private: diff --git a/src/files/files.hpp b/src/files/files.hpp index 3c602b66..e1ead5c7 100644 --- a/src/files/files.hpp +++ b/src/files/files.hpp @@ -63,8 +63,13 @@ namespace files { /// @brief Read JSON or BJSON file /// @param file *.json or *.bjson file dv::value read_json(const fs::path& file); + dv::value read_binary_json(const fs::path& file); + + /// @brief Read TOML file + /// @param file *.toml file dv::value read_toml(const fs::path& file); + std::vector read_list(const fs::path& file); bool is_data_file(const fs::path& file); diff --git a/src/logic/scripting/lua/libfile.cpp b/src/logic/scripting/lua/libfile.cpp index 30c0e204..52f7e4db 100644 --- a/src/logic/scripting/lua/libfile.cpp +++ b/src/logic/scripting/lua/libfile.cpp @@ -247,6 +247,14 @@ static int l_file_gzip_decompress(lua::State* L) { } } +static int l_file_read_combined_list(lua::State* L) { + std::string path = lua::require_string(L, 1); + if (path.find(':') != std::string::npos) { + throw std::runtime_error("entry point must not be specified"); + } + return lua::pushvalue(L, engine->getResPaths()->readCombinedList(path)); +} + const luaL_Reg filelib[] = { {"exists", lua::wrap}, {"find", lua::wrap}, @@ -265,4 +273,5 @@ const luaL_Reg filelib[] = { {"write", lua::wrap}, {"gzip_compress", lua::wrap}, {"gzip_decompress", lua::wrap}, + {"read_combined_list", lua::wrap}, {NULL, NULL}};