#ifndef CONTENT_CONTENT_H_ #define CONTENT_CONTENT_H_ #include #include #include #include #include #include #include "../typedefs.h" using DrawGroups = std::set; class Block; class ItemDef; class Content; enum class contenttype { none, block, item }; inline const char* contenttype_name(contenttype type) { switch (type) { case contenttype::none: return "none"; case contenttype::block: return "block"; case contenttype::item: return "item"; default: return "unknown"; } } class namereuse_error: public std::runtime_error { contenttype type; public: namereuse_error(const std::string& msg, contenttype type) : std::runtime_error(msg), type(type) {} inline contenttype getType() const { return type; } }; class ContentBuilder { std::unordered_map blockDefs; std::vector blockIds; std::unordered_map itemDefs; std::vector itemIds; public: ~ContentBuilder(); void add(Block* def); void add(ItemDef* def); Block* createBlock(std::string id); ItemDef* createItem(std::string id); void checkIdentifier(std::string id); contenttype checkContentType(std::string id); Content* build(); }; /* Runtime defs cache: indices */ class ContentIndices { std::vector blockDefs; std::vector itemDefs; public: ContentIndices(std::vector blockDefs, std::vector itemDefs); inline Block* getBlockDef(blockid_t id) const { if (id >= blockDefs.size()) return nullptr; return blockDefs[id]; } 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(); } }; /* Content is a definitions repository */ class Content { std::unordered_map blockDefs; std::unordered_map itemDefs; std::unique_ptr indices; public: DrawGroups* const drawGroups; Content(ContentIndices* indices, DrawGroups* drawGroups, std::unordered_map blockDefs, std::unordered_map itemDefs); ~Content(); inline ContentIndices* getIndices() const { return indices.get(); } Block* findBlock(std::string id) const; Block* requireBlock(std::string id) const; ItemDef* findItem(std::string id) const; ItemDef* requireItem(std::string id) const; }; #endif // CONTENT_CONTENT_H_