adding/removing packs update
This commit is contained in:
parent
657b09da9e
commit
7c4c511826
@ -24,6 +24,10 @@ void PacksManager::scan() {
|
||||
}
|
||||
}
|
||||
|
||||
void PacksManager::exclude(const std::string& id) {
|
||||
packs.erase(id);
|
||||
}
|
||||
|
||||
std::vector<std::string> PacksManager::getAllNames() const {
|
||||
std::vector<std::string> names;
|
||||
for (auto& entry : packs) {
|
||||
@ -82,7 +86,7 @@ static bool resolve_dependencies (
|
||||
auto found = packs.find(dep.id);
|
||||
bool exists = found != packs.end();
|
||||
if (!exists && dep.level == DependencyLevel::required) {
|
||||
throw contentpack_error(pack->id, pack->folder, "missing dependency '"+dep.id+"'");
|
||||
throw contentpack_error(dep.id, fs::path(), "dependency of '"+pack->id+"'");
|
||||
}
|
||||
if (!exists) {
|
||||
// ignored for optional or weak dependencies
|
||||
@ -144,3 +148,11 @@ std::vector<std::string> PacksManager::assembly(const std::vector<std::string>&
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
std::vector<std::string> PacksManager::getNames(const std::vector<ContentPack>& packs) {
|
||||
std::vector<std::string> result;
|
||||
for (const auto& pack : packs) {
|
||||
result.push_back(pack.id);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -22,6 +22,9 @@ public:
|
||||
/// Scanning order depends on sources order
|
||||
void scan();
|
||||
|
||||
/// @brief Remove pack from manager to make it invisible for assembly(...)
|
||||
void exclude(const std::string& id);
|
||||
|
||||
/// @brief Get all found packs
|
||||
std::vector<std::string> getAllNames() const;
|
||||
|
||||
@ -36,6 +39,9 @@ public:
|
||||
/// @throws contentpack_error if required dependency not found or
|
||||
/// circular dependency detected
|
||||
std::vector<std::string> assembly(const std::vector<std::string>& names) const;
|
||||
|
||||
/// @brief Collect all pack names (identifiers) into a new vector
|
||||
static std::vector<std::string> getNames(const std::vector<ContentPack>& packs);
|
||||
};
|
||||
|
||||
#endif // CONTENT_PACKS_MANAGER_H_
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "../items/Inventory.h"
|
||||
|
||||
#include "../data/dynamic.h"
|
||||
#include "../core_defs.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
@ -496,7 +497,9 @@ void WorldFiles::write(const World* world, const Content* content) {
|
||||
|
||||
if (world) {
|
||||
writeWorldInfo(world);
|
||||
writePacks(world);
|
||||
if (!fs::exists(getPacksFile())) {
|
||||
writePacks(world->getPacks());
|
||||
}
|
||||
}
|
||||
if (generatorTestMode) {
|
||||
return;
|
||||
@ -508,13 +511,8 @@ void WorldFiles::write(const World* world, const Content* content) {
|
||||
writeRegions(storages, inventoriesFolder, REGION_LAYER_INVENTORIES);
|
||||
}
|
||||
|
||||
void WorldFiles::writePacks(const World* world) {
|
||||
void WorldFiles::writePacks(const std::vector<ContentPack>& packs) {
|
||||
auto packsFile = getPacksFile();
|
||||
if (fs::is_regular_file(packsFile)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& packs = world->getPacks();
|
||||
std::stringstream ss;
|
||||
ss << "# autogenerated; do not modify\n";
|
||||
for (const auto& pack : packs) {
|
||||
@ -559,56 +557,15 @@ bool WorldFiles::readWorldInfo(World* world) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void WorldFiles::addPack(const World* world, const std::string& id) {
|
||||
fs::path file = getPacksFile();
|
||||
if (!fs::is_regular_file(file)) {
|
||||
if (!fs::is_directory(directory)) {
|
||||
fs::create_directories(directory);
|
||||
}
|
||||
writePacks(world);
|
||||
}
|
||||
auto packs = files::read_list(file);
|
||||
packs.push_back(id);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "# autogenerated; do not modify\n";
|
||||
for (const auto& pack : packs) {
|
||||
ss << pack << "\n";
|
||||
}
|
||||
files::write_string(file, ss.str());
|
||||
}
|
||||
|
||||
void WorldFiles::removePack(const World* world, const std::string& id) {
|
||||
fs::path file = getPacksFile();
|
||||
if (!fs::is_regular_file(file)) {
|
||||
if (!fs::is_directory(directory)) {
|
||||
fs::create_directories(directory);
|
||||
}
|
||||
writePacks(world);
|
||||
}
|
||||
auto packs = files::read_list(file);
|
||||
auto found = std::find(packs.begin(), packs.end(), id);
|
||||
if (found != packs.end()) {
|
||||
packs.erase(found);
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "# autogenerated; do not modify\n";
|
||||
for (const auto& pack : packs) {
|
||||
ss << pack << "\n";
|
||||
}
|
||||
files::write_string(file, ss.str());
|
||||
|
||||
// erase invalid indices
|
||||
static void erase_pack_indices(dynamic::Map* root, const std::string& id) {
|
||||
auto prefix = id+":";
|
||||
auto root = files::read_json(getIndicesFile());
|
||||
auto blocks = root->list("blocks");
|
||||
for (uint i = 0; i < blocks->size(); i++) {
|
||||
auto name = blocks->str(i);
|
||||
if (name.find(prefix) != 0)
|
||||
continue;
|
||||
auto value = blocks->getValueWriteable(i);
|
||||
value->value = "core:air";
|
||||
value->value = CORE_AIR;
|
||||
}
|
||||
|
||||
auto items = root->list("items");
|
||||
@ -617,7 +574,14 @@ void WorldFiles::removePack(const World* world, const std::string& id) {
|
||||
if (name.find(prefix) != 0)
|
||||
continue;
|
||||
auto value = items->getValueWriteable(i);
|
||||
value->value = "core:empty";
|
||||
value->value = CORE_EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
void WorldFiles::removeIndices(const std::vector<std::string>& packs) {
|
||||
auto root = files::read_json(getIndicesFile());
|
||||
for (const auto& id : packs) {
|
||||
erase_pack_indices(root.get(), id);
|
||||
}
|
||||
files::write_json(getIndicesFile(), root.get());
|
||||
}
|
||||
|
||||
@ -1,7 +1,14 @@
|
||||
#ifndef FILES_WORLDFILES_H_
|
||||
#define FILES_WORLDFILES_H_
|
||||
|
||||
#include "files.h"
|
||||
#include "../typedefs.h"
|
||||
#include "../settings.h"
|
||||
#include "../content/ContentPack.h"
|
||||
#include "../voxels/Chunk.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
@ -11,12 +18,6 @@
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include "glm/gtx/hash.hpp"
|
||||
|
||||
#include "files.h"
|
||||
#include "../typedefs.h"
|
||||
#include "../settings.h"
|
||||
|
||||
#include "../voxels/Chunk.h"
|
||||
|
||||
inline constexpr uint REGION_HEADER_SIZE = 10;
|
||||
|
||||
inline constexpr uint REGION_LAYER_VOXELS = 0;
|
||||
@ -146,19 +147,10 @@ public:
|
||||
/// @param content world content
|
||||
void write(const World* world, const Content* content);
|
||||
|
||||
void writePacks(const World* world);
|
||||
void writePacks(const std::vector<ContentPack>& packs);
|
||||
void writeIndices(const ContentIndices* indices);
|
||||
|
||||
/// @brief Append pack to the packs list without duplicate check and
|
||||
/// dependencies resolve
|
||||
/// @param world target world
|
||||
/// @param id pack id
|
||||
void addPack(const World* world, const std::string& id);
|
||||
|
||||
/// @brief Remove pack from the list (does not remove indices)
|
||||
/// @param world target world
|
||||
/// @param id pack id
|
||||
void removePack(const World* world, const std::string& id);
|
||||
void removeIndices(const std::vector<std::string>& packs);
|
||||
|
||||
static const inline std::string WORLD_FILE = "world.json";
|
||||
};
|
||||
|
||||
@ -118,27 +118,6 @@ static void reopen_world(Engine* engine, World* world) {
|
||||
menus::open_world(wname, engine, true);
|
||||
}
|
||||
|
||||
// FIXME: dependency levels
|
||||
static bool try_add_dependency(Engine* engine, World* world, const ContentPack& pack, std::string& missing) {
|
||||
auto paths = engine->getPaths();
|
||||
for (const auto& dependency : pack.dependencies) {
|
||||
fs::path folder = ContentPack::findPack(
|
||||
paths,
|
||||
world->wfile->directory,
|
||||
dependency.id
|
||||
);
|
||||
if (!fs::is_directory(folder)) {
|
||||
missing = dependency.id;
|
||||
return true;
|
||||
}
|
||||
if (!world->hasPack(dependency.id)) {
|
||||
world->wfile->addPack(world, dependency.id);
|
||||
}
|
||||
}
|
||||
world->wfile->addPack(world, pack.id);
|
||||
return false;
|
||||
}
|
||||
|
||||
void menus::remove_packs(
|
||||
Engine* engine,
|
||||
LevelController* controller,
|
||||
@ -161,9 +140,16 @@ void menus::remove_packs(
|
||||
|
||||
runnable removeFunc = [=]() {
|
||||
controller->saveWorld();
|
||||
auto manager = engine->createPacksManager(world->wfile->directory);;
|
||||
manager.scan();
|
||||
|
||||
auto names = PacksManager::getNames(world->getPacks());
|
||||
for (const auto& id : packsToRemove) {
|
||||
world->wfile->removePack(world, id);
|
||||
manager.exclude(id);
|
||||
names.erase(std::find(names.begin(), names.end(), id));
|
||||
}
|
||||
world->wfile->removeIndices(packsToRemove);
|
||||
world->wfile->writePacks(manager.getAll(names));
|
||||
reopen_world(engine, world);
|
||||
};
|
||||
|
||||
@ -210,15 +196,21 @@ void create_content_panel(Engine* engine, LevelController* controller) {
|
||||
auto panel = menus::create_packs_panel(scanned, engine, true,
|
||||
[=](const ContentPack& pack) {
|
||||
auto world = level->getWorld();
|
||||
std::string missing;
|
||||
if (try_add_dependency(engine, world, pack, missing)) {
|
||||
auto new_packs = PacksManager::getNames(world->getPacks());
|
||||
new_packs.push_back(pack.id);
|
||||
|
||||
auto manager = engine->createPacksManager(world->wfile->directory);
|
||||
manager.scan();
|
||||
try {
|
||||
new_packs = manager.assembly(new_packs);
|
||||
} catch (const contentpack_error& err) {
|
||||
guiutil::alert(
|
||||
gui, langs::get(L"error.dependency-not-found")+
|
||||
L": "+util::str2wstr_utf8(missing)
|
||||
L": "+util::str2wstr_utf8(err.getPackId())
|
||||
);
|
||||
return;
|
||||
}
|
||||
world->wfile->addPack(world, pack.id);
|
||||
world->wfile->writePacks(manager.getAll(new_packs));
|
||||
controller->saveWorld();
|
||||
reopen_world(engine, world);
|
||||
}, nullptr);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user