From f9d391e05a702e43009376eec52bfb46e28ad63b Mon Sep 17 00:00:00 2001 From: MihailRis Date: Mon, 8 Apr 2024 13:09:38 +0300 Subject: [PATCH] PacksManager added to engine --- src/content/ContentPack.cpp | 29 ------------------ src/content/ContentPack.h | 17 ----------- src/content/PacksManager.cpp | 30 +++++++++++++------ src/content/PacksManager.h | 9 ++++-- src/engine.cpp | 39 ++++++++++++++++++++++--- src/frontend/menu/menu_create_world.cpp | 1 + src/frontend/menu/menu_pause.cpp | 13 +++++++-- src/util/listutil.cpp | 17 +++++++++++ src/util/listutil.h | 5 +--- 9 files changed, 93 insertions(+), 67 deletions(-) create mode 100644 src/util/listutil.cpp diff --git a/src/content/ContentPack.cpp b/src/content/ContentPack.cpp index 4370c7f8..59382539 100644 --- a/src/content/ContentPack.cpp +++ b/src/content/ContentPack.cpp @@ -113,21 +113,6 @@ void ContentPack::scanFolder( } } -void ContentPack::scan( - fs::path rootfolder, - EnginePaths* paths, - std::vector& packs -) { - scanFolder(paths->getResources()/fs::path("content"), packs); - scanFolder(paths->getUserfiles()/fs::path("content"), packs); - scanFolder(rootfolder, packs); -} - -void ContentPack::scan(EnginePaths* paths, - std::vector& packs) { - scan(paths->getWorldFolder()/fs::path("content"), paths, packs); -} - std::vector ContentPack::worldPacksList(fs::path folder) { fs::path listfile = folder / fs::path("packs.list"); if (!fs::is_regular_file(listfile)) { @@ -154,20 +139,6 @@ fs::path ContentPack::findPack(const EnginePaths* paths, fs::path worldDir, std: return folder; } -void ContentPack::readPacks(const EnginePaths* paths, - std::vector& packs, - const std::vector& packnames, - fs::path worldDir) { - for (const auto& name : packnames) { - fs::path packfolder = ContentPack::findPack(paths, worldDir, name); - if (!fs::is_directory(packfolder)) { - throw contentpack_error(name, packfolder, - "could not to find pack '"+name+"'"); - } - packs.push_back(ContentPack::read(packfolder)); - } -} - ContentPackRuntime::ContentPackRuntime( ContentPack info, std::unique_ptr env diff --git a/src/content/ContentPack.h b/src/content/ContentPack.h index e5a61f2d..7f6d024e 100644 --- a/src/content/ContentPack.h +++ b/src/content/ContentPack.h @@ -63,16 +63,6 @@ struct ContentPack { fs::path folder, std::vector& packs ); - - static void scan( - fs::path folder, - EnginePaths* paths, - std::vector& packs - ); - static void scan( - EnginePaths* paths, - std::vector& packs - ); static std::vector worldPacksList(fs::path folder); @@ -81,13 +71,6 @@ struct ContentPack { fs::path worldDir, std::string name ); - - static void readPacks( - const EnginePaths* paths, - std::vector& packs, - const std::vector& names, - fs::path worldDir - ); }; struct ContentPackStats { diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index 6ff3a020..f0abc79d 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -24,7 +24,7 @@ void PacksManager::scan() { } } -std::vector PacksManager::getAllNames() { +std::vector PacksManager::getAllNames() const { std::vector names; for (auto& entry : packs) { names.push_back(entry.first); @@ -32,8 +32,20 @@ std::vector PacksManager::getAllNames() { return names; } -static contentpack_error on_circular_dependency(std::queue& queue) { - ContentPack* lastPack = queue.back(); +std::vector PacksManager::getAll(const std::vector& names) const { + std::vector packsList; + for (auto& name : names) { + auto found = packs.find(name); + if (found == packs.end()) { + throw contentpack_error(name, fs::path(""), "pack not found"); + } + packsList.push_back(found->second); + } + return packsList; +} + +static contentpack_error on_circular_dependency(std::queue& queue) { + const ContentPack* lastPack = queue.back(); // circular dependency std::stringstream ss; ss << "circular dependency: " << lastPack->id; @@ -55,11 +67,11 @@ static contentpack_error on_circular_dependency(std::queue& queue) /// @return true if all dependencies are already added or not found (optional/weak) /// @throws contentpack_error if required dependency is not found static bool resolve_dependencies ( - ContentPack* pack, - std::unordered_map& packs, + const ContentPack* pack, + const std::unordered_map& packs, std::vector& allNames, std::vector& added, - std::queue& queue, + std::queue& queue, bool resolveWeaks ) { bool satisfied = true; @@ -91,11 +103,11 @@ static bool resolve_dependencies ( return satisfied; } -std::vector PacksManager::assembly(const std::vector& names) { +std::vector PacksManager::assembly(const std::vector& names) const { std::vector allNames = names; std::vector added; - std::queue queue; - std::queue queue2; + std::queue queue; + std::queue queue2; for (auto& name : names) { auto found = packs.find(name); diff --git a/src/content/PacksManager.h b/src/content/PacksManager.h index 96071e01..575feb20 100644 --- a/src/content/PacksManager.h +++ b/src/content/PacksManager.h @@ -23,14 +23,19 @@ public: void scan(); /// @brief Get all found packs - std::vector getAllNames(); + std::vector getAllNames() const; + + /// @brief Get packs by names (id) + /// @param names pack names + /// @throws contentpack_error if pack not found + std::vector getAll(const std::vector& names) const; /// @brief Resolve all dependencies and fix packs order /// @param names required packs (method can add extra packs) /// @return resulting ordered vector of pack names /// @throws contentpack_error if required dependency not found or /// circular dependency detected - std::vector assembly(const std::vector& names); + std::vector assembly(const std::vector& names) const; }; #endif // CONTENT_PACKS_MANAGER_H_ diff --git a/src/engine.cpp b/src/engine.cpp index 8c1d0a41..c9b8a735 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -11,6 +11,7 @@ #include "content/Content.h" #include "content/ContentLoader.h" #include "content/ContentPack.h" +#include "content/PacksManager.h" #include "core_defs.h" #include "files/engine_paths.h" #include "files/files.h" @@ -27,6 +28,7 @@ #include "graphics/ui/elements/containers.h" #include "logic/scripting/scripting.h" #include "util/platform.h" +#include "util/listutil.h" #include "voxels/DefaultWorldGenerator.h" #include "voxels/FlatWorldGenerator.h" #include "window/Camera.h" @@ -227,6 +229,22 @@ void Engine::loadContent() { corecontent::setup(&contentBuilder); paths->setContentPacks(&contentPacks); + std::vector names; + for (auto& pack : contentPacks) { + names.push_back(pack.id); + } + + // --------------------------------------------- + PacksManager manager; + manager.setSources({ + paths->getWorldFolder()/fs::path("content"), + paths->getUserfiles()/fs::path("content"), + paths->getResources()/fs::path("content") + }); + manager.scan(); + auto allnames = manager.getAllNames(); + // --------------------------------------------- + std::vector resRoots; std::vector srcPacks = contentPacks; contentPacks.clear(); @@ -281,15 +299,28 @@ void Engine::loadContent() { void Engine::loadWorldContent(const fs::path& folder) { contentPacks.clear(); auto packNames = ContentPack::worldPacksList(folder); - ContentPack::readPacks(paths, contentPacks, packNames, folder); + PacksManager manager; + manager.setSources({ + folder/fs::path("content"), + paths->getUserfiles()/fs::path("content"), + paths->getResources()/fs::path("content") + }); + manager.scan(); + contentPacks = manager.getAll(manager.assembly(packNames)); paths->setWorldFolder(folder); loadContent(); } void Engine::loadAllPacks() { - auto resdir = paths->getResources(); - contentPacks.clear(); - ContentPack::scan(paths, contentPacks); + PacksManager manager; + manager.setSources({ + paths->getWorldFolder()/fs::path("content"), + paths->getUserfiles()/fs::path("content"), + paths->getResources()/fs::path("content") + }); + manager.scan(); + auto allnames = manager.getAllNames(); + contentPacks = manager.getAll(manager.assembly(allnames)); } double Engine::getDelta() const { diff --git a/src/frontend/menu/menu_create_world.cpp b/src/frontend/menu/menu_create_world.cpp index b72d1153..f1fcc7c0 100644 --- a/src/frontend/menu/menu_create_world.cpp +++ b/src/frontend/menu/menu_create_world.cpp @@ -3,6 +3,7 @@ #include "../../engine.h" #include "../../files/WorldFiles.h" +#include "../../content/PacksManager.h" #include "../../graphics/ui/elements/containers.h" #include "../../graphics/ui/elements/controls.h" #include "../../graphics/ui/gui_util.h" diff --git a/src/frontend/menu/menu_pause.cpp b/src/frontend/menu/menu_pause.cpp index 7d42c15b..06175ee5 100644 --- a/src/frontend/menu/menu_pause.cpp +++ b/src/frontend/menu/menu_pause.cpp @@ -2,6 +2,7 @@ #include "menu_commons.h" #include "../../coders/png.h" +#include "../../content/PacksManager.h" #include "../../content/ContentLUT.h" #include "../../engine.h" #include "../../files/WorldFiles.h" @@ -181,8 +182,16 @@ void create_content_panel(Engine* engine, LevelController* controller) { auto menu = engine->getGUI()->getMenu(); auto mainPanel = menus::create_page(engine, "content", 550, 0.0f, 5); - std::vector scanned; - ContentPack::scan(engine->getPaths(), scanned); + auto paths = engine->getPaths(); + PacksManager manager; + manager.setSources({ + paths->getWorldFolder()/fs::path("content"), + paths->getUserfiles()/fs::path("content"), + paths->getResources()/fs::path("content") + }); + manager.scan(); + + std::vector scanned = manager.getAll(manager.getAllNames()); for (const auto& pack : engine->getContentPacks()) { for (size_t i = 0; i < scanned.size(); i++) { if (scanned[i].id == pack.id) { diff --git a/src/util/listutil.cpp b/src/util/listutil.cpp new file mode 100644 index 00000000..92b24c63 --- /dev/null +++ b/src/util/listutil.cpp @@ -0,0 +1,17 @@ +#include "listutil.h" +#include "../util/stringutil.h" + +#include + +std::string util::to_string(const std::vector& vec) { + std::stringstream ss; + ss << "["; + for (size_t i = 0; i < vec.size(); i++) { + ss << util::quote(vec.at(i)); + if (i < vec.size()-1) { + ss << ", "; + } + } + ss << "]"; + return ss.str(); +} diff --git a/src/util/listutil.h b/src/util/listutil.h index 911aacba..68871146 100644 --- a/src/util/listutil.h +++ b/src/util/listutil.h @@ -11,10 +11,7 @@ namespace util { return std::find(vec.begin(), vec.end(), value) != vec.end(); } - template - bool contains(const std::queue& queue, const T& value) { - return std::find(queue.begin(), queue.end(), value) != queue.end(); - } + std::string to_string(const std::vector& vec); } #endif // UTIL_LISTUTIL_H_