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> PacksManager::getAllNames() const {
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
for (auto& entry : packs) {
|
for (auto& entry : packs) {
|
||||||
@ -82,7 +86,7 @@ static bool resolve_dependencies (
|
|||||||
auto found = packs.find(dep.id);
|
auto found = packs.find(dep.id);
|
||||||
bool exists = found != packs.end();
|
bool exists = found != packs.end();
|
||||||
if (!exists && dep.level == DependencyLevel::required) {
|
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) {
|
if (!exists) {
|
||||||
// ignored for optional or weak dependencies
|
// ignored for optional or weak dependencies
|
||||||
@ -144,3 +148,11 @@ std::vector<std::string> PacksManager::assembly(const std::vector<std::string>&
|
|||||||
}
|
}
|
||||||
return added;
|
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
|
/// Scanning order depends on sources order
|
||||||
void scan();
|
void scan();
|
||||||
|
|
||||||
|
/// @brief Remove pack from manager to make it invisible for assembly(...)
|
||||||
|
void exclude(const std::string& id);
|
||||||
|
|
||||||
/// @brief Get all found packs
|
/// @brief Get all found packs
|
||||||
std::vector<std::string> getAllNames() const;
|
std::vector<std::string> getAllNames() const;
|
||||||
|
|
||||||
@ -36,6 +39,9 @@ public:
|
|||||||
/// @throws contentpack_error if required dependency not found or
|
/// @throws contentpack_error if required dependency not found or
|
||||||
/// circular dependency detected
|
/// circular dependency detected
|
||||||
std::vector<std::string> assembly(const std::vector<std::string>& names) const;
|
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_
|
#endif // CONTENT_PACKS_MANAGER_H_
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include "../items/Inventory.h"
|
#include "../items/Inventory.h"
|
||||||
|
|
||||||
#include "../data/dynamic.h"
|
#include "../data/dynamic.h"
|
||||||
|
#include "../core_defs.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -496,7 +497,9 @@ void WorldFiles::write(const World* world, const Content* content) {
|
|||||||
|
|
||||||
if (world) {
|
if (world) {
|
||||||
writeWorldInfo(world);
|
writeWorldInfo(world);
|
||||||
writePacks(world);
|
if (!fs::exists(getPacksFile())) {
|
||||||
|
writePacks(world->getPacks());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (generatorTestMode) {
|
if (generatorTestMode) {
|
||||||
return;
|
return;
|
||||||
@ -508,13 +511,8 @@ void WorldFiles::write(const World* world, const Content* content) {
|
|||||||
writeRegions(storages, inventoriesFolder, REGION_LAYER_INVENTORIES);
|
writeRegions(storages, inventoriesFolder, REGION_LAYER_INVENTORIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldFiles::writePacks(const World* world) {
|
void WorldFiles::writePacks(const std::vector<ContentPack>& packs) {
|
||||||
auto packsFile = getPacksFile();
|
auto packsFile = getPacksFile();
|
||||||
if (fs::is_regular_file(packsFile)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& packs = world->getPacks();
|
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "# autogenerated; do not modify\n";
|
ss << "# autogenerated; do not modify\n";
|
||||||
for (const auto& pack : packs) {
|
for (const auto& pack : packs) {
|
||||||
@ -559,56 +557,15 @@ bool WorldFiles::readWorldInfo(World* world) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldFiles::addPack(const World* world, const std::string& id) {
|
static void erase_pack_indices(dynamic::Map* root, 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
|
|
||||||
auto prefix = id+":";
|
auto prefix = id+":";
|
||||||
auto root = files::read_json(getIndicesFile());
|
|
||||||
auto blocks = root->list("blocks");
|
auto blocks = root->list("blocks");
|
||||||
for (uint i = 0; i < blocks->size(); i++) {
|
for (uint i = 0; i < blocks->size(); i++) {
|
||||||
auto name = blocks->str(i);
|
auto name = blocks->str(i);
|
||||||
if (name.find(prefix) != 0)
|
if (name.find(prefix) != 0)
|
||||||
continue;
|
continue;
|
||||||
auto value = blocks->getValueWriteable(i);
|
auto value = blocks->getValueWriteable(i);
|
||||||
value->value = "core:air";
|
value->value = CORE_AIR;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto items = root->list("items");
|
auto items = root->list("items");
|
||||||
@ -617,7 +574,14 @@ void WorldFiles::removePack(const World* world, const std::string& id) {
|
|||||||
if (name.find(prefix) != 0)
|
if (name.find(prefix) != 0)
|
||||||
continue;
|
continue;
|
||||||
auto value = items->getValueWriteable(i);
|
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());
|
files::write_json(getIndicesFile(), root.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,14 @@
|
|||||||
#ifndef FILES_WORLDFILES_H_
|
#ifndef FILES_WORLDFILES_H_
|
||||||
#define 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 <map>
|
||||||
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -11,12 +18,6 @@
|
|||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include "glm/gtx/hash.hpp"
|
#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_HEADER_SIZE = 10;
|
||||||
|
|
||||||
inline constexpr uint REGION_LAYER_VOXELS = 0;
|
inline constexpr uint REGION_LAYER_VOXELS = 0;
|
||||||
@ -146,19 +147,10 @@ public:
|
|||||||
/// @param content world content
|
/// @param content world content
|
||||||
void write(const World* world, const Content* 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);
|
void writeIndices(const ContentIndices* indices);
|
||||||
|
|
||||||
/// @brief Append pack to the packs list without duplicate check and
|
void removeIndices(const std::vector<std::string>& packs);
|
||||||
/// 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);
|
|
||||||
|
|
||||||
static const inline std::string WORLD_FILE = "world.json";
|
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);
|
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(
|
void menus::remove_packs(
|
||||||
Engine* engine,
|
Engine* engine,
|
||||||
LevelController* controller,
|
LevelController* controller,
|
||||||
@ -161,9 +140,16 @@ void menus::remove_packs(
|
|||||||
|
|
||||||
runnable removeFunc = [=]() {
|
runnable removeFunc = [=]() {
|
||||||
controller->saveWorld();
|
controller->saveWorld();
|
||||||
|
auto manager = engine->createPacksManager(world->wfile->directory);;
|
||||||
|
manager.scan();
|
||||||
|
|
||||||
|
auto names = PacksManager::getNames(world->getPacks());
|
||||||
for (const auto& id : packsToRemove) {
|
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);
|
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,
|
auto panel = menus::create_packs_panel(scanned, engine, true,
|
||||||
[=](const ContentPack& pack) {
|
[=](const ContentPack& pack) {
|
||||||
auto world = level->getWorld();
|
auto world = level->getWorld();
|
||||||
std::string missing;
|
auto new_packs = PacksManager::getNames(world->getPacks());
|
||||||
if (try_add_dependency(engine, world, pack, missing)) {
|
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(
|
guiutil::alert(
|
||||||
gui, langs::get(L"error.dependency-not-found")+
|
gui, langs::get(L"error.dependency-not-found")+
|
||||||
L": "+util::str2wstr_utf8(missing)
|
L": "+util::str2wstr_utf8(err.getPackId())
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world->wfile->addPack(world, pack.id);
|
world->wfile->writePacks(manager.getAll(new_packs));
|
||||||
controller->saveWorld();
|
controller->saveWorld();
|
||||||
reopen_world(engine, world);
|
reopen_world(engine, world);
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user