#pragma once #include #include #include #include "Content.hpp" #include "ContentPack.hpp" #include "items/ItemDef.hpp" #include "objects/EntityDef.hpp" #include "voxels/Block.hpp" template class ContentUnitBuilder { std::unordered_map& 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 defs; std::vector names; ContentUnitBuilder( std::unordered_map& 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(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 blockMaterials; UptrsMap skeletons; UptrsMap packs; std::unordered_map allNames; public: ContentUnitBuilder blocks {allNames, ContentType::BLOCK}; ContentUnitBuilder items {allNames, ContentType::ITEM}; ContentUnitBuilder entities {allNames, ContentType::ENTITY}; ResourceIndicesSet resourceIndices {}; ~ContentBuilder(); void add(std::unique_ptr pack); void add(std::unique_ptr skeleton); BlockMaterial& createBlockMaterial(const std::string& id); std::unique_ptr build(); };