81 lines
2.2 KiB
C++
81 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include "Content.hpp"
|
|
#include "ContentPack.hpp"
|
|
#include "items/ItemDef.hpp"
|
|
#include "objects/EntityDef.hpp"
|
|
#include "voxels/Block.hpp"
|
|
|
|
template <class T>
|
|
class ContentUnitBuilder {
|
|
std::unordered_map<std::string, ContentType>& allNames;
|
|
ContentType type;
|
|
|
|
void checkIdentifier(const std::string& id) {
|
|
const auto& found = allNames.find(id);
|
|
if (found != allNames.end()) {
|
|
throw namereuse_error(
|
|
"name " + id + " is already used", found->second
|
|
);
|
|
}
|
|
}
|
|
public:
|
|
UptrsMap<std::string, T> defs;
|
|
std::vector<std::string> names;
|
|
|
|
ContentUnitBuilder(
|
|
std::unordered_map<std::string, ContentType>& allNames, ContentType type
|
|
)
|
|
: allNames(allNames), type(type) {
|
|
}
|
|
|
|
T& create(const std::string& id) {
|
|
auto found = defs.find(id);
|
|
if (found != defs.end()) {
|
|
return *found->second;
|
|
}
|
|
checkIdentifier(id);
|
|
allNames[id] = type;
|
|
names.push_back(id);
|
|
defs[id] = std::make_unique<T>(id);
|
|
return *defs[id];
|
|
}
|
|
// Only fetch existing definition, return null otherwise.
|
|
T* get(const std::string& id) {
|
|
auto found = defs.find(id);
|
|
if (found != defs.end()) {
|
|
return &*found->second;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
auto build() {
|
|
return std::move(defs);
|
|
}
|
|
};
|
|
|
|
class ContentBuilder {
|
|
UptrsMap<std::string, BlockMaterial> blockMaterials;
|
|
UptrsMap<std::string, rigging::SkeletonConfig> skeletons;
|
|
UptrsMap<std::string, ContentPackRuntime> packs;
|
|
std::unordered_map<std::string, ContentType> allNames;
|
|
public:
|
|
ContentUnitBuilder<Block> blocks {allNames, ContentType::BLOCK};
|
|
ContentUnitBuilder<ItemDef> items {allNames, ContentType::ITEM};
|
|
ContentUnitBuilder<EntityDef> entities {allNames, ContentType::ENTITY};
|
|
ResourceIndicesSet resourceIndices {};
|
|
|
|
~ContentBuilder();
|
|
|
|
void add(std::unique_ptr<ContentPackRuntime> pack);
|
|
void add(std::unique_ptr<rigging::SkeletonConfig> skeleton);
|
|
|
|
BlockMaterial& createBlockMaterial(const std::string& id);
|
|
|
|
std::unique_ptr<Content> build();
|
|
};
|