diff --git a/doc/en/scripting/builtins/libapp.md b/doc/en/scripting/builtins/libapp.md index a0a17970..c2c8f71d 100644 --- a/doc/en/scripting/builtins/libapp.md +++ b/doc/en/scripting/builtins/libapp.md @@ -48,7 +48,8 @@ app.reconfig_packs( ) ``` -Updates the pack configuration, checking its correctness (dependencies and availability of packs). +Updates the packs configuration, checking its correctness (dependencies and availability of packs). +Automatically adds dependencies. To remove all packs from the configuration, you can use `pack.get_installed()`: @@ -58,6 +59,16 @@ app.reconfig_packs({}, pack.get_installed()) In this case, `base` will also be removed from the configuration. +```lua +app.config_packs( +-- expected set of packs (excluding dependencies) +packs: table +) +``` + +Updates the packs configuration, automatically removing unspecified ones, adding those missing in the previous configuration. +Uses app.reconfig_packs. + ```lua app.new_world( -- world name diff --git a/doc/en/scripting/builtins/libpack.md b/doc/en/scripting/builtins/libpack.md index 8d1d97b8..e643e95e 100644 --- a/doc/en/scripting/builtins/libpack.md +++ b/doc/en/scripting/builtins/libpack.md @@ -96,8 +96,14 @@ Returns information about the pack (not necessarily installed). - `~` - weak for example `!teal` -To obtain information about multiple packs, use table of ids to avoid re-scanning. +To obtain information about multiple packs, use table of ids to avoid re-scanning:one ```lua pack.get_info(packids: table) -> {id={...}, id2={...}, ...} ``` + +```lua +pack.assemble(packis: table) -> table +``` + +Checks the configuration for correctness and adds dependencies, returning the complete configuration. diff --git a/doc/ru/scripting/builtins/libapp.md b/doc/ru/scripting/builtins/libapp.md index a30a96e4..7887bcdf 100644 --- a/doc/ru/scripting/builtins/libapp.md +++ b/doc/ru/scripting/builtins/libapp.md @@ -49,6 +49,7 @@ app.reconfig_packs( ``` Обновляет конфигурацию паков, проверяя её корректность (зависимости и доступность паков). +Автоматически добавляет зависимости. Для удаления всех паков из конфигурации можно использовать `pack.get_installed()`: @@ -58,6 +59,16 @@ app.reconfig_packs({}, pack.get_installed()) В этом случае из конфигурации будет удалён и `base`. +```lua +app.config_packs( + -- ожидаемый набор паков (без учёта зависимостей) + packs: table +) +``` + +Обновляет конфигурацию паков, автоматически удаляя лишние, добавляя отсутствующие в прошлой конфигурации. +Использует app.reconfig_packs. + ```lua app.new_world( -- название мира diff --git a/doc/ru/scripting/builtins/libpack.md b/doc/ru/scripting/builtins/libpack.md index 93eecfc8..a3f174ff 100644 --- a/doc/ru/scripting/builtins/libpack.md +++ b/doc/ru/scripting/builtins/libpack.md @@ -84,8 +84,14 @@ pack.get_info(packid: str) -> { например `!teal` Для получения информации о нескольких паках используйте таблицу id, чтобы не -производить сканирование для каждого пака. +производить сканирование для каждого пака: ```lua pack.get_info(packids: table) -> {id={...}, id2={...}, ...} ``` + +```lua +pack.assemble(packis: table) -> table +``` + +Проверяет корректность конфигурации и добавляет зависимости, возвращая полную. diff --git a/res/modules/tests_util.lua b/res/modules/tests_util.lua index ef6a5d2e..1e2207c2 100644 --- a/res/modules/tests_util.lua +++ b/res/modules/tests_util.lua @@ -1,7 +1,7 @@ local util = {} function util.create_demo_world(generator) - app.reconfig_packs({"base"}, {}) + app.config_packs({"base"}) app.new_world("demo", "2019", generator or "core:default") end diff --git a/res/scripts/stdlib.lua b/res/scripts/stdlib.lua index 611a94d2..791cfdf4 100644 --- a/res/scripts/stdlib.lua +++ b/res/scripts/stdlib.lua @@ -37,6 +37,26 @@ if app then app.tick = coroutine.yield app.get_version = core.get_version app.get_setting_info = core.get_setting_info + + function app.config_packs(packs_list) + -- Check if packs are valid and add dependencies to the configuration + packs_list = pack.assemble(packs_list) + + local installed = pack.get_installed() + local toremove = {} + for _, packid in ipairs(installed) do + if not table.has(packs_list, packid) then + table.insert(toremove, packid) + end + end + local toadd = {} + for _, packid in ipairs(packs_list) do + if not table.has(installed, packid) then + table.insert(toadd, packid) + end + end + app.reconfig_packs(toadd, toremove) + end function app.quit() local tb = debug.get_traceback(1) diff --git a/src/content/PacksManager.cpp b/src/content/PacksManager.cpp index 370bed98..04eeb241 100644 --- a/src/content/PacksManager.cpp +++ b/src/content/PacksManager.cpp @@ -116,7 +116,7 @@ static bool resolve_dependencies( return satisfied; } -std::vector PacksManager::assembly( +std::vector PacksManager::assemble( const std::vector& names ) const { std::vector allNames = names; diff --git a/src/content/PacksManager.hpp b/src/content/PacksManager.hpp index 3784bbfb..6d77e471 100644 --- a/src/content/PacksManager.hpp +++ b/src/content/PacksManager.hpp @@ -38,7 +38,7 @@ public: /// @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 assemble(const std::vector& names ) const; /// @brief Collect all pack names (identifiers) into a new vector diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 2d73c131..39feb2bc 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -346,7 +346,7 @@ void Engine::loadContent() { paths.setContentPacks(&contentPacks); PacksManager manager = createPacksManager(paths.getCurrentWorldFolder()); manager.scan(); - names = manager.assembly(names); + names = manager.assemble(names); contentPacks = manager.getAll(names); auto corePack = ContentPack::createCore(paths); @@ -417,7 +417,7 @@ void Engine::loadWorldContent(const fs::path& folder) { paths.getResourcesFolder()/fs::path("content") }); manager.scan(); - contentPacks = manager.getAll(manager.assembly(packNames)); + contentPacks = manager.getAll(manager.assemble(packNames)); paths.setCurrentWorldFolder(folder); loadContent(); } @@ -426,7 +426,7 @@ void Engine::loadAllPacks() { PacksManager manager = createPacksManager(paths.getCurrentWorldFolder()); manager.scan(); auto allnames = manager.getAllNames(); - contentPacks = manager.getAll(manager.assembly(allnames)); + contentPacks = manager.getAll(manager.assemble(allnames)); } void Engine::setScreen(std::shared_ptr screen) { diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index e98e0dae..615e26eb 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -322,7 +322,7 @@ void EngineController::reconfigPacks( manager.exclude(id); names.erase(std::find(names.begin(), names.end(), id)); } - names = manager.assembly(names); + names = manager.assemble(names); engine.getContentPacks() = manager.getAll(names); } catch (const contentpack_error& err) { throw std::runtime_error( diff --git a/src/logic/scripting/lua/libs/libapp.cpp b/src/logic/scripting/lua/libs/libapp.cpp index fa3b0453..bd61bc7a 100644 --- a/src/logic/scripting/lua/libs/libapp.cpp +++ b/src/logic/scripting/lua/libs/libapp.cpp @@ -1,5 +1,6 @@ #include "api_lua.hpp" const luaL_Reg applib[] = { + // see libcore.cpp an stdlib.lua {NULL, NULL} }; diff --git a/src/logic/scripting/lua/libs/libpack.cpp b/src/logic/scripting/lua/libs/libpack.cpp index 81843caf..3b56f96d 100644 --- a/src/logic/scripting/lua/libs/libpack.cpp +++ b/src/logic/scripting/lua/libs/libpack.cpp @@ -211,10 +211,38 @@ static int l_pack_get_base_packs(lua::State* L) { return 1; } +static int l_pack_assemble(lua::State* L) { + if (!lua::istable(L, 1)) { + throw std::runtime_error("table expected"); + } + std::vector ids; + size_t len = lua::objlen(L, 1); + for (size_t i = 1; i <= len; i++) { + lua::rawgeti(L, i); + ids.push_back(lua::require_string(L, -1)); + lua::pop(L); + } + fs::path worldFolder(""); + if (level) { + worldFolder = level->getWorld()->wfile->getFolder(); + } + auto manager = engine->createPacksManager(worldFolder); + manager.scan(); + ids = std::move(manager.assemble(ids)); + + lua::createtable(L, ids.size(), 0); + for (size_t i = 0; i < ids.size(); i++) { + lua::pushstring(L, ids[i]); + lua::rawseti(L, i + 1); + } + return 1; +} + const luaL_Reg packlib[] = { {"get_folder", lua::wrap}, {"get_installed", lua::wrap}, {"get_available", lua::wrap}, {"get_info", lua::wrap}, {"get_base_packs", lua::wrap}, + {"assemble", lua::wrap}, {NULL, NULL}};