From 7749675a61724f7236c12cee6186c5b28343499f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 13 Apr 2025 13:53:59 +0300 Subject: [PATCH] add EnumMetadata --- src/coders/GLSLExtension.cpp | 29 +++------ src/content/Content.hpp | 38 ------------ src/content/ContentLoader.cpp | 28 ++++----- src/content/content_fwd.hpp | 14 +++++ src/data/StructLayout.hpp | 1 - src/graphics/core/PostEffect.hpp | 9 +++ src/logic/EngineController.cpp | 3 +- .../scripting/lua/libs/lib__rigidbody.cpp | 12 ++-- src/logic/scripting/lua/libs/libblock.cpp | 3 +- src/objects/Entities.cpp | 7 +-- src/objects/Player.hpp | 1 - src/physics/Hitbox.cpp | 20 ------ src/physics/Hitbox.hpp | 9 ++- src/presets/NotePreset.cpp | 34 ++--------- src/presets/NotePreset.hpp | 10 ++- src/util/EnumMetadata.hpp | 61 +++++++++++++++++++ src/voxels/Block.cpp | 56 ----------------- src/voxels/Block.hpp | 18 ++++-- src/world/World.cpp | 3 +- src/world/files/WorldFiles.cpp | 6 +- 20 files changed, 156 insertions(+), 206 deletions(-) create mode 100644 src/util/EnumMetadata.hpp diff --git a/src/coders/GLSLExtension.cpp b/src/coders/GLSLExtension.cpp index 8af419e0..c9e31e31 100644 --- a/src/coders/GLSLExtension.cpp +++ b/src/coders/GLSLExtension.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "GLSLExtension.hpp" #include @@ -95,22 +96,6 @@ inline void source_line(std::stringstream& ss, uint linenum) { ss << "#line " << linenum << "\n"; } -static std::optional param_type_from( - const std::string& name -) { - static const std::unordered_map typeNames { - {"float", Type::FLOAT}, - {"vec2", Type::VEC2}, - {"vec3", Type::VEC3}, - {"vec4", Type::VEC4}, - }; - const auto& found = typeNames.find(name); - if (found == typeNames.end()) { - return std::nullopt; - } - return found->second; -} - static Value default_value_for(Type type) { switch (type) { case Type::FLOAT: @@ -212,11 +197,13 @@ public: } bool processParamDirective() { + using Param = PostEffect::Param; + skipWhitespace(false); // Parse type name auto typeName = parseName(); - auto type = param_type_from(typeName); - if (!type.has_value()) { + Param::Type type; + if (!Param::TypeMeta.getItem(typeName, type)) { throw error("unsupported param type " + util::quote(typeName)); } skipWhitespace(false); @@ -228,17 +215,17 @@ public: skipWhitespace(false); ss << "uniform " << typeName << " " << paramName << ";\n"; - auto defValue = default_value_for(type.value()); + auto defValue = default_value_for(type); // Parse default value if (peekNoJump() == '=') { skip(1); skipWhitespace(false); - defValue = parseDefaultValue(type.value(), typeName); + defValue = parseDefaultValue(type, typeName); } skipLine(); - params[paramName] = PostEffect::Param(type.value(), std::move(defValue)); + params[paramName] = PostEffect::Param(type, std::move(defValue)); return false; } diff --git a/src/content/Content.hpp b/src/content/Content.hpp index bbdf2013..539325a8 100644 --- a/src/content/Content.hpp +++ b/src/content/Content.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -25,23 +24,6 @@ namespace rigging { class SkeletonConfig; } -constexpr const char* ContentType_name(ContentType type) { - switch (type) { - case ContentType::NONE: - return "none"; - case ContentType::BLOCK: - return "block"; - case ContentType::ITEM: - return "item"; - case ContentType::ENTITY: - return "entity"; - case ContentType::GENERATOR: - return "generator"; - default: - return "unknown"; - } -} - class namereuse_error : public std::runtime_error { ContentType type; public: @@ -185,26 +167,6 @@ public: } }; -constexpr const char* to_string(ResourceType type) { - switch (type) { - case ResourceType::CAMERA: - return "camera"; - case ResourceType::POST_EFFECT_SLOT: - return "post-effect-slot"; - default: - return "unknown"; - } -} - -inline std::optional ResourceType_from(std::string_view str) { - if (str == "camera") { - return ResourceType::CAMERA; - } else if (str == "post-effect-slot") { - return ResourceType::POST_EFFECT_SLOT; - } - return std::nullopt; -} - using ResourceIndicesSet = ResourceIndices[RESOURCE_TYPES_COUNT]; /// @brief Content is a definitions repository diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index 3fb2b8f6..9b4326b5 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "ContentLoader.hpp" #include @@ -259,28 +260,25 @@ void ContentLoader::loadBlock( } // block model - std::string modelTypeName = to_string(def.model); + std::string modelTypeName = BlockModelMeta.getNameString(def.model); root.at("model").get(modelTypeName); root.at("model-name").get(def.modelName); - if (auto model = BlockModel_from(modelTypeName)) { - if (*model == BlockModel::custom && def.customModelRaw == nullptr) { + if (BlockModelMeta.getItem(modelTypeName, def.model)) { + if (def.model == BlockModel::custom && def.customModelRaw == nullptr) { if (root.has("model-primitives")) { def.customModelRaw = root["model-primitives"]; } else if (def.modelName.empty()) { throw std::runtime_error(name + ": no 'model-primitives' or 'model-name' found"); } } - def.model = *model; } else if (!modelTypeName.empty()) { logger.error() << "unknown model: " << modelTypeName; def.model = BlockModel::none; } - std::string cullingModeName = to_string(def.culling); + std::string cullingModeName = CullingModeMeta.getNameString(def.culling); root.at("culling").get(cullingModeName); - if (auto mode = CullingMode_from(cullingModeName)) { - def.culling = *mode; - } else { + if (!CullingModeMeta.getItem(cullingModeName, def.culling)) { logger.error() << "unknown culling mode: " << cullingModeName; } @@ -518,9 +516,7 @@ void ContentLoader::loadEntity( std::string bodyTypeName; root.at("body-type").get(bodyTypeName); - if (auto bodyType = BodyType_from(bodyTypeName)) { - def.bodyType = *bodyType; - } + BodyTypeMeta.getItem(bodyTypeName, def.bodyType); root.at("skeleton-name").get(def.skeletonName); root.at("blocking").get(def.blocking); @@ -799,8 +795,9 @@ void ContentLoader::load() { if (io::exists(resourcesFile)) { auto resRoot = io::read_json(resourcesFile); for (const auto& [key, arr] : resRoot.asObject()) { - if (auto resType = ResourceType_from(key)) { - loadResources(*resType, arr); + ResourceType type; + if (ResourceTypeMeta.getItem(key, type)) { + loadResources(type, arr); } else { // Ignore unknown resources logger.warning() << "unknown resource type: " << key; @@ -813,8 +810,9 @@ void ContentLoader::load() { if (io::exists(aliasesFile)) { auto resRoot = io::read_json(aliasesFile); for (const auto& [key, arr] : resRoot.asObject()) { - if (auto resType = ResourceType_from(key)) { - loadResourceAliases(*resType, arr); + ResourceType type; + if (ResourceTypeMeta.getItem(key, type)) { + loadResourceAliases(type, arr); } else { // Ignore unknown resources logger.warning() << "unknown resource type: " << key; diff --git a/src/content/content_fwd.hpp b/src/content/content_fwd.hpp index f6e2ffb7..f3b4061a 100644 --- a/src/content/content_fwd.hpp +++ b/src/content/content_fwd.hpp @@ -1,12 +1,21 @@ #pragma once #include "typedefs.hpp" +#include "util/EnumMetadata.hpp" class Content; class ContentPackRuntime; enum class ContentType { NONE, BLOCK, ITEM, ENTITY, GENERATOR }; +VC_ENUM_METADATA(ContentType) + {"none", ContentType::NONE}, + {"block", ContentType::BLOCK}, + {"item", ContentType::ITEM}, + {"entity", ContentType::ENTITY}, + {"generator", ContentType::GENERATOR}, +VC_ENUM_END + enum class ResourceType : size_t { CAMERA, POST_EFFECT_SLOT, @@ -15,3 +24,8 @@ enum class ResourceType : size_t { inline constexpr auto RESOURCE_TYPES_COUNT = static_cast(ResourceType::LAST) + 1; + +VC_ENUM_METADATA(ResourceType) + {"camera", ResourceType::CAMERA}, + {"post-effect-slot", ResourceType::POST_EFFECT_SLOT}, +VC_ENUM_END diff --git a/src/data/StructLayout.hpp b/src/data/StructLayout.hpp index 47d59b3b..8d35a226 100644 --- a/src/data/StructLayout.hpp +++ b/src/data/StructLayout.hpp @@ -4,7 +4,6 @@ #include #include #include -#include #include "typedefs.hpp" #include "interfaces/Serializable.hpp" diff --git a/src/graphics/core/PostEffect.hpp b/src/graphics/core/PostEffect.hpp index 4624ec40..9c4bd84f 100644 --- a/src/graphics/core/PostEffect.hpp +++ b/src/graphics/core/PostEffect.hpp @@ -7,6 +7,7 @@ #include #include "data/dv_fwd.hpp" +#include "util/EnumMetadata.hpp" class Shader; @@ -14,6 +15,14 @@ class PostEffect { public: struct Param { enum class Type { FLOAT, VEC2, VEC3, VEC4 }; + + VC_ENUM_METADATA(Type) + {"float", Type::FLOAT}, + {"vec2", Type::VEC2}, + {"vec3", Type::VEC3}, + {"vec4", Type::VEC4}, + VC_ENUM_END + using Value = std::variant; Type type; diff --git a/src/logic/EngineController.cpp b/src/logic/EngineController.cpp index ec125909..9cfbba30 100644 --- a/src/logic/EngineController.cpp +++ b/src/logic/EngineController.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "EngineController.hpp" #include @@ -164,7 +165,7 @@ static dv::value create_missing_content_report( auto root = dv::object(); auto& contentEntries = root.list("content"); for (auto& entry : report->getMissingContent()) { - std::string contentName = ContentType_name(entry.type); + std::string contentName = ContentTypeMeta.getNameString(entry.type); auto& contentEntry = contentEntries.object(); contentEntry["type"] = contentName; contentEntry["name"] = entry.name; diff --git a/src/logic/scripting/lua/libs/lib__rigidbody.cpp b/src/logic/scripting/lua/libs/lib__rigidbody.cpp index a5d3563a..d0e66940 100644 --- a/src/logic/scripting/lua/libs/lib__rigidbody.cpp +++ b/src/logic/scripting/lua/libs/lib__rigidbody.cpp @@ -1,3 +1,5 @@ +#define VC_ENABLE_REFLECTION + #include "util/stringutil.hpp" #include "libentity.hpp" @@ -96,8 +98,8 @@ static int l_set_crouching(lua::State* L) { static int l_get_body_type(lua::State* L) { if (auto entity = get_entity(L, 1)) { - return lua::pushstring( - L, to_string(entity->getRigidbody().hitbox.type) + return lua::pushlstring( + L, BodyTypeMeta.getName(entity->getRigidbody().hitbox.type) ); } return 0; @@ -105,9 +107,9 @@ static int l_get_body_type(lua::State* L) { static int l_set_body_type(lua::State* L) { if (auto entity = get_entity(L, 1)) { - if (auto type = BodyType_from(lua::tostring(L, 2))) { - entity->getRigidbody().hitbox.type = *type; - } else { + if (!BodyTypeMeta.getItem( + lua::tostring(L, 2), entity->getRigidbody().hitbox.type + )) { throw std::runtime_error( "unknown body type " + util::quote(lua::tostring(L, 2)) ); diff --git a/src/logic/scripting/lua/libs/libblock.cpp b/src/logic/scripting/lua/libs/libblock.cpp index 3c813bd8..8963926f 100644 --- a/src/logic/scripting/lua/libs/libblock.cpp +++ b/src/logic/scripting/lua/libs/libblock.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "content/Content.hpp" #include "content/ContentLoader.hpp" #include "content/ContentControl.hpp" @@ -311,7 +312,7 @@ static int l_get_textures(lua::State* L) { static int l_get_model(lua::State* L) { if (auto def = require_block(L)) { - return lua::pushstring(L, to_string(def->model)); + return lua::pushlstring(L, BlockModelMeta.getName(def->model)); } return 0; } diff --git a/src/objects/Entities.cpp b/src/objects/Entities.cpp index 4e9f8894..4cfe1b29 100644 --- a/src/objects/Entities.cpp +++ b/src/objects/Entities.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "Entities.hpp" #include @@ -216,9 +217,7 @@ void Entities::loadEntity(const dv::value& map, Entity entity) { dv::get_vec(bodymap, "vel", body.hitbox.velocity); std::string bodyTypeName; map.at("type").get(bodyTypeName); - if (auto bodyType = BodyType_from(bodyTypeName)) { - body.hitbox.type = *bodyType; - } + BodyTypeMeta.getItem(bodyTypeName, body.hitbox.type); bodymap["crouch"].asBoolean(body.hitbox.crouching); bodymap["damping"].asNumber(body.hitbox.linearDamping); } @@ -329,7 +328,7 @@ dv::value Entities::serialize(const Entity& entity) { if (def.save.body.settings) { bodymap["damping"] = rigidbody.hitbox.linearDamping; if (hitbox.type != def.bodyType) { - bodymap["type"] = to_string(hitbox.type); + bodymap["type"] = BodyTypeMeta.getNameString(hitbox.type); } if (hitbox.crouching) { bodymap["crouch"] = hitbox.crouching; diff --git a/src/objects/Player.hpp b/src/objects/Player.hpp index cc60eb3f..c4d847b3 100644 --- a/src/objects/Player.hpp +++ b/src/objects/Player.hpp @@ -2,7 +2,6 @@ #include #include -#include #include "interfaces/Serializable.hpp" #include "settings.hpp" diff --git a/src/physics/Hitbox.cpp b/src/physics/Hitbox.cpp index f80dc0c5..83ad823c 100644 --- a/src/physics/Hitbox.cpp +++ b/src/physics/Hitbox.cpp @@ -2,26 +2,6 @@ #include -std::optional BodyType_from(std::string_view str) { - if (str == "kinematic") { - return BodyType::KINEMATIC; - } else if (str == "dynamic") { - return BodyType::DYNAMIC; - } else if (str == "static") { - return BodyType::STATIC; - } - return std::nullopt; -} - -std::string to_string(BodyType type) { - switch (type) { - case BodyType::KINEMATIC: return "kinematic"; - case BodyType::DYNAMIC: return "dynamic"; - case BodyType::STATIC: return "static"; - default: return "unknown"; - } -} - Hitbox::Hitbox(BodyType type, glm::vec3 position, glm::vec3 halfsize) : type(type), position(position), diff --git a/src/physics/Hitbox.hpp b/src/physics/Hitbox.hpp index 2c5a4e78..e825cefe 100644 --- a/src/physics/Hitbox.hpp +++ b/src/physics/Hitbox.hpp @@ -2,10 +2,10 @@ #include "maths/aabb.hpp" #include "typedefs.hpp" +#include "util/EnumMetadata.hpp" #include #include -#include #include #include @@ -41,8 +41,11 @@ enum class BodyType { STATIC, KINEMATIC, DYNAMIC }; -std::optional BodyType_from(std::string_view str); -std::string to_string(BodyType type); +VC_ENUM_METADATA(BodyType) + {"static", BodyType::STATIC}, + {"kinematic", BodyType::KINEMATIC}, + {"dynamic", BodyType::DYNAMIC}, +VC_ENUM_END struct Hitbox { BodyType type; diff --git a/src/presets/NotePreset.cpp b/src/presets/NotePreset.cpp index e03fd741..59865e80 100644 --- a/src/presets/NotePreset.cpp +++ b/src/presets/NotePreset.cpp @@ -1,37 +1,13 @@ +#define VC_ENABLE_REFLECTION + #include "NotePreset.hpp" - -#include -#include - #include "data/dv_util.hpp" -std::string to_string(NoteDisplayMode mode) { - static std::vector names = { - "static_billboard", - "y_free_billboard", - "xy_free_billboard", - "projected" - }; - return names.at(static_cast(mode)); -} - -std::optional NoteDisplayMode_from(std::string_view s) { - static std::map> map { - {"static_billboard", NoteDisplayMode::STATIC_BILLBOARD}, - {"y_free_billboard", NoteDisplayMode::Y_FREE_BILLBOARD}, - {"xy_free_billboard", NoteDisplayMode::XY_FREE_BILLBOARD}, - {"projected", NoteDisplayMode::PROJECTED} - }; - const auto& found = map.find(s); - if (found == map.end()) { - return std::nullopt; - } - return found->second; -} +#include dv::value NotePreset::serialize() const { return dv::object({ - {"display", to_string(displayMode)}, + {"display", NoteDisplayModeMeta.getNameString(displayMode)}, {"color", dv::to_value(color)}, {"scale", scale}, {"render_distance", renderDistance}, @@ -42,7 +18,7 @@ dv::value NotePreset::serialize() const { void NotePreset::deserialize(const dv::value& src) { if (src.has("display")) { - displayMode = NoteDisplayMode_from(src["display"].asString()).value(); + NoteDisplayModeMeta.getItem(src["display"].asString(), displayMode); } if (src.has("color")) { dv::get_vec(src["color"], color); diff --git a/src/presets/NotePreset.hpp b/src/presets/NotePreset.hpp index bc478fb4..fecdaf18 100644 --- a/src/presets/NotePreset.hpp +++ b/src/presets/NotePreset.hpp @@ -2,10 +2,10 @@ #include #include -#include #include #include "interfaces/Serializable.hpp" +#include "util/EnumMetadata.hpp" enum class NoteDisplayMode { STATIC_BILLBOARD, @@ -14,8 +14,12 @@ enum class NoteDisplayMode { PROJECTED }; -std::string to_string(NoteDisplayMode mode); -std::optional NoteDisplayMode_from(std::string_view s); +VC_ENUM_METADATA(NoteDisplayMode) + {"static_billboard", NoteDisplayMode::STATIC_BILLBOARD}, + {"y_free_billboard", NoteDisplayMode::Y_FREE_BILLBOARD}, + {"xy_free_billboard", NoteDisplayMode::XY_FREE_BILLBOARD}, + {"projected", NoteDisplayMode::PROJECTED}, +VC_ENUM_END struct NotePreset : public Serializable { NoteDisplayMode displayMode = NoteDisplayMode::STATIC_BILLBOARD; diff --git a/src/util/EnumMetadata.hpp b/src/util/EnumMetadata.hpp new file mode 100644 index 00000000..35f2b0d1 --- /dev/null +++ b/src/util/EnumMetadata.hpp @@ -0,0 +1,61 @@ +#pragma once + +#ifdef VC_ENABLE_REFLECTION +#define VC_ENUM_METADATA(NAME) static inline util::EnumMetadata NAME##Meta { +#define VC_ENUM_END }; + +#include +#include +#include + +namespace util { + template + class EnumMetadata { + public: + EnumMetadata( + std::initializer_list> items + ) + : items(items) { + for (const auto& [name, item] : items) { + names[item] = name; + } + } + + std::string_view getName(EnumT item) const { + const auto& found = names.find(item); + if (found == names.end()) { + return ""; + } + return found->second; + } + + std::string getNameString(EnumT item) const { + return std::string(getName(item)); + } + + bool getItem(std::string_view name, EnumT& dst) const { + const auto& found = items.find(name); + if (found == items.end()) { + return false; + } + dst = found->second; + return true; + } + + size_t size() const { + return items.size(); + } + private: + std::map items; + std::map names; + }; +} + +#else +#include + +#define VC_ENUM_METADATA(NAME) \ + struct NAME##__PAIR {const char* n; NAME i;}; \ + [[maybe_unused]] static inline std::initializer_list NAME##_PAIRS { +#define VC_ENUM_END }; +#endif // VC_ENABLE_REFLECTION diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 7f08b3a7..7ef9d317 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -18,62 +18,6 @@ dv::value BlockMaterial::serialize() const { }); } -std::string to_string(BlockModel model) { - switch (model) { - case BlockModel::none: - return "none"; - case BlockModel::block: - return "block"; - case BlockModel::xsprite: - return "X"; - case BlockModel::aabb: - return "aabb"; - case BlockModel::custom: - return "custom"; - default: - return "unknown"; - } -} - -std::optional BlockModel_from(std::string_view str) { - if (str == "none") { - return BlockModel::none; - } else if (str == "block") { - return BlockModel::block; - } else if (str == "X") { - return BlockModel::xsprite; - } else if (str == "aabb") { - return BlockModel::aabb; - } else if (str == "custom") { - return BlockModel::custom; - } - return std::nullopt; -} - -std::string to_string(CullingMode mode) { - switch (mode) { - case CullingMode::DEFAULT: - return "default"; - case CullingMode::OPTIONAL: - return "optional"; - case CullingMode::DISABLED: - return "disabled"; - default: - return "unknown"; - } -} - -std::optional CullingMode_from(std::string_view str) { - if (str == "default") { - return CullingMode::DEFAULT; - } else if (str == "optional") { - return CullingMode::OPTIONAL; - } else if (str == "disabled") { - return CullingMode::DISABLED; - } - return std::nullopt; -} - CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) : axes({axisX, axisY, axisZ}) { fix = glm::ivec3(0); diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 972b405f..6776ffa5 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -10,6 +9,7 @@ #include "maths/UVRegion.hpp" #include "maths/aabb.hpp" #include "typedefs.hpp" +#include "util/EnumMetadata.hpp" struct ParticlesPreset; @@ -93,8 +93,13 @@ enum class BlockModel { custom }; -std::string to_string(BlockModel model); -std::optional BlockModel_from(std::string_view str); +VC_ENUM_METADATA(BlockModel) + {"none", BlockModel::none}, + {"block", BlockModel::block}, + {"X", BlockModel::xsprite}, + {"aabb", BlockModel::aabb}, + {"custom", BlockModel::custom}, +VC_ENUM_END enum class CullingMode { DEFAULT, @@ -102,8 +107,11 @@ enum class CullingMode { DISABLED, }; -std::string to_string(CullingMode mode); -std::optional CullingMode_from(std::string_view str); +VC_ENUM_METADATA(CullingMode) + {"default", CullingMode::DEFAULT}, + {"optional", CullingMode::OPTIONAL}, + {"disabled", CullingMode::DISABLED}, +VC_ENUM_END using BoxModel = AABB; diff --git a/src/world/World.cpp b/src/world/World.cpp index 68842ae3..96264336 100644 --- a/src/world/World.cpp +++ b/src/world/World.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "World.hpp" #include @@ -49,7 +50,7 @@ void World::updateTimers(float delta) { void World::writeResources(const Content& content) { auto root = dv::object(); for (size_t typeIndex = 0; typeIndex < RESOURCE_TYPES_COUNT; typeIndex++) { - auto typeName = to_string(static_cast(typeIndex)); + auto typeName = ResourceTypeMeta.getNameString(static_cast(typeIndex)); auto& list = root.list(typeName); auto& indices = content.resourceIndices[typeIndex]; for (size_t i = 0; i < indices.size(); i++) { diff --git a/src/world/files/WorldFiles.cpp b/src/world/files/WorldFiles.cpp index 3617ad7c..e4137f03 100644 --- a/src/world/files/WorldFiles.cpp +++ b/src/world/files/WorldFiles.cpp @@ -1,3 +1,4 @@ +#define VC_ENABLE_REFLECTION #include "WorldFiles.hpp" #include @@ -182,8 +183,9 @@ bool WorldFiles::readResourcesData(const Content& content) { } auto root = io::read_json(file); for (const auto& [key, arr] : root.asObject()) { - if (auto resType = ResourceType_from(key)) { - read_resources_data(content, arr, *resType); + ResourceType type; + if (ResourceTypeMeta.getItem(key, type)) { + read_resources_data(content, arr, type); } else { logger.warning() << "unknown resource type: " << key; }