refactor Content

This commit is contained in:
MihailRis
2024-06-25 22:37:53 +03:00
parent f3c5afa1ab
commit ee9f1639e9
25 changed files with 180 additions and 209 deletions
+9 -41
View File
@@ -12,62 +12,30 @@
#include "../logic/scripting/scripting.hpp"
ContentIndices::ContentIndices(
std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs
) : blockDefs(std::move(blockDefs)),
itemDefs(std::move(itemDefs))
std::vector<Block*> blocks,
std::vector<ItemDef*> items
) : blocks(std::move(blocks)),
items(std::move(items))
{}
Content::Content(
std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
ContentUnitDefs<Block> blocks,
ContentUnitDefs<ItemDef> items,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
) : blockDefs(std::move(blockDefs)),
itemDefs(std::move(itemDefs)),
indices(std::move(indices)),
) : indices(std::move(indices)),
packs(std::move(packs)),
blockMaterials(std::move(blockMaterials)),
blocks(std::move(blocks)),
items(std::move(items)),
drawGroups(std::move(drawGroups))
{}
Content::~Content() {
}
Block* Content::findBlock(const std::string& id) const {
auto found = blockDefs.find(id);
if (found == blockDefs.end()) {
return nullptr;
}
return found->second.get();
}
Block& Content::requireBlock(const std::string& id) const {
auto found = blockDefs.find(id);
if (found == blockDefs.end()) {
throw std::runtime_error("missing block "+id);
}
return *found->second;
}
ItemDef* Content::findItem(const std::string& id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
return nullptr;
}
return found->second.get();
}
ItemDef& Content::requireItem(const std::string& id) const {
auto found = itemDefs.find(id);
if (found == itemDefs.end()) {
throw std::runtime_error("missing item "+id);
}
return *found->second;
}
const BlockMaterial* Content::findBlockMaterial(const std::string& id) const {
auto found = blockMaterials.find(id);
if (found == blockMaterials.end()) {
+50 -39
View File
@@ -43,61 +43,79 @@ public:
}
};
template<class T>
class ContentUnitIndices {
std::vector<T*> defs;
public:
ContentUnitIndices(std::vector<T*> defs) : defs(std::move(defs)) {}
inline T* get(blockid_t id) const {
if (id >= defs.size()) {
return nullptr;
}
return defs[id];
}
inline size_t count() const {
return defs.size();
}
inline const T* const* getDefs() const {
return defs.data();
}
};
/// @brief Runtime defs cache: indices
class ContentIndices {
std::vector<Block*> blockDefs;
std::vector<ItemDef*> itemDefs;
public:
ContentUnitIndices<Block> blocks;
ContentUnitIndices<ItemDef> items;
ContentIndices(
std::vector<Block*> blockDefs,
std::vector<ItemDef*> itemDefs
);
};
inline Block* getBlockDef(blockid_t id) const {
if (id >= blockDefs.size())
template<class T>
class ContentUnitDefs {
std::unordered_map<std::string, std::unique_ptr<T>> defs;
public:
ContentUnitDefs(std::unordered_map<std::string, std::unique_ptr<T>> defs)
: defs(std::move(defs)) {
}
T* find(const std::string& id) const {
const auto& found = defs.find(id);
if (found == defs.end()) {
return nullptr;
return blockDefs[id];
}
return found->second.get();
}
inline ItemDef* getItemDef(itemid_t id) const {
if (id >= itemDefs.size())
return nullptr;
return itemDefs[id];
}
inline size_t countBlockDefs() const {
return blockDefs.size();
}
inline size_t countItemDefs() const {
return itemDefs.size();
}
// use this for critical spots to prevent range check overhead
const Block* const* getBlockDefs() const {
return blockDefs.data();
}
const ItemDef* const* getItemDefs() const {
return itemDefs.data();
T& require(const std::string& id) const {
const auto& found = defs.find(id);
if (found == defs.end()) {
throw std::runtime_error("missing content unit "+id);
}
return *found->second;
}
};
/* Content is a definitions repository */
/// @brief Content is a definitions repository
class Content {
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs;
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs;
std::unique_ptr<ContentIndices> indices;
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs;
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials;
public:
ContentUnitDefs<Block> blocks;
ContentUnitDefs<ItemDef> items;
std::unique_ptr<DrawGroups> const drawGroups;
Content(
std::unique_ptr<ContentIndices> indices,
std::unique_ptr<DrawGroups> drawGroups,
std::unordered_map<std::string, std::unique_ptr<Block>> blockDefs,
std::unordered_map<std::string, std::unique_ptr<ItemDef>> itemDefs,
ContentUnitDefs<Block> blocks,
ContentUnitDefs<ItemDef> items,
std::unordered_map<std::string, std::unique_ptr<ContentPackRuntime>> packs,
std::unordered_map<std::string, std::unique_ptr<BlockMaterial>> blockMaterials
);
@@ -106,15 +124,8 @@ public:
inline ContentIndices* getIndices() const {
return indices.get();
}
Block* findBlock(const std::string& id) const;
Block& requireBlock(const std::string& id) const;
ItemDef* findItem(const std::string& id) const;
ItemDef& requireItem(const std::string& id) const;
const BlockMaterial* findBlockMaterial(const std::string& id) const;
const ContentPackRuntime* getPackRuntime(const std::string& id) const;
const std::unordered_map<std::string, std::unique_ptr<BlockMaterial>>& getBlockMaterials() const;
+2 -2
View File
@@ -99,11 +99,11 @@ std::unique_ptr<Content> ContentBuilder::build() {
// Now, it's time to resolve foreign keys
for (Block* def : blockDefsIndices) {
def->rt.pickingItem = content->requireItem(def->pickingItem).rt.id;
def->rt.pickingItem = content->items.require(def->pickingItem).rt.id;
}
for (ItemDef* def : itemDefsIndices) {
def->rt.placingBlock = content->requireBlock(def->placingBlock).rt.id;
def->rt.placingBlock = content->blocks.require(def->placingBlock).rt.id;
}
return content;
+37 -46
View File
@@ -10,29 +10,45 @@
#include <memory>
template<typename I, class T>
static void init(std::vector<I>& ids, std::vector<std::string>& names,
const ContentUnitIndices<T>& indices, size_t count) {
for (size_t i = 0; i < count; i++) {
ids.push_back(i);
}
for (size_t i = 0; i < indices.count(); i++) {
names.push_back(indices.get(i)->name);
}
for (size_t i = indices.count(); i < count; i++) {
names.emplace_back("");
}
}
ContentLUT::ContentLUT(const Content* content, size_t blocksCount, size_t itemsCount) {
auto* indices = content->getIndices();
for (size_t i = 0; i < blocksCount; i++) {
blocks.push_back(i);
}
for (size_t i = 0; i < indices->countBlockDefs(); i++) {
blockNames.push_back(indices->getBlockDef(i)->name);
}
for (size_t i = indices->countBlockDefs(); i < blocksCount; i++) {
blockNames.emplace_back("");
}
init(blocks, blockNames, indices->blocks, blocksCount);
init(items, itemNames, indices->items, itemsCount);
}
for (size_t i = 0; i < itemsCount; i++) {
items.push_back(i);
}
for (size_t i = 0; i < indices->countItemDefs(); i++) {
itemNames.push_back(indices->getItemDef(i)->name);
}
for (size_t i = indices->countItemDefs(); i < itemsCount; i++) {
itemNames.emplace_back();
template<class T>
static void setup_lut(ContentLUT* lut, const ContentUnitDefs<T>& defs, dynamic::List* list) {
if (list) {
for (size_t i = 0; i < list->size(); i++) {
std::string name = list->str(i);
if (auto def = defs.find(name)) {
lut->setBlock(i, name, def->rt.id);
} else {
lut->setBlock(i, name, BLOCK_VOID);
}
}
}
}
template<class T> static constexpr size_t get_entries_count(
const ContentUnitIndices<T>& indices, dynamic::List* list) {
return list ? std::max(list->size(), indices.count()) : indices.count();
}
std::shared_ptr<ContentLUT> ContentLUT::create(
const fs::path& filename,
const Content* content
@@ -42,38 +58,13 @@ std::shared_ptr<ContentLUT> ContentLUT::create(
auto itemlist = root->list("items");
auto* indices = content->getIndices();
size_t blocks_c = blocklist
? std::max(blocklist->size(), indices->countBlockDefs())
: indices->countBlockDefs();
size_t items_c = itemlist
? std::max(itemlist->size(), indices->countItemDefs())
: indices->countItemDefs();
size_t blocks_c = get_entries_count(indices->blocks, blocklist);
size_t items_c = get_entries_count(indices->items, itemlist);
auto lut = std::make_shared<ContentLUT>(content, blocks_c, items_c);
if (blocklist) {
for (size_t i = 0; i < blocklist->size(); i++) {
std::string name = blocklist->str(i);
Block* def = content->findBlock(name);
if (def) {
lut->setBlock(i, name, def->rt.id);
} else {
lut->setBlock(i, name, BLOCK_VOID);
}
}
}
if (itemlist) {
for (size_t i = 0; i < itemlist->size(); i++) {
std::string name = itemlist->str(i);
ItemDef* def = content->findItem(name);
if (def) {
lut->setItem(i, name, def->rt.id);
} else {
lut->setItem(i, name, ITEM_VOID);
}
}
}
setup_lut(lut.get(), content->blocks, blocklist);
setup_lut(lut.get(), content->items, itemlist);
if (lut->hasContentReorder() || lut->hasMissingContent()) {
return lut;