From eab13e2ae53cdb07646c036127e9a6f096a803b0 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Tue, 21 May 2024 13:38:05 +0300 Subject: [PATCH] Track uuid->type mapping for ecs components and throw an exception when the same uuid is used for different components --- .../psemek/ecs/detail/component_registry.hpp | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/libs/ecs/include/psemek/ecs/detail/component_registry.hpp b/libs/ecs/include/psemek/ecs/detail/component_registry.hpp index 49cc9fa1..00d6d649 100644 --- a/libs/ecs/include/psemek/ecs/detail/component_registry.hpp +++ b/libs/ecs/include/psemek/ecs/detail/component_registry.hpp @@ -4,16 +4,50 @@ #include #include #include +#include +#include namespace psemek::ecs::detail { + struct duplicate_uuid_exception + : util::exception + { + duplicate_uuid_exception(util::uuid const & uuid, std::type_info const & type1, std::type_info const & type2, boost::stacktrace::stacktrace stacktrace = {}) + : util::exception(util::to_string("Found duplicate UUID ", uuid, " for components ", util::type_name(type1), " and ", util::type_name(type2)), std::move(stacktrace)) + , uuid_(uuid) + , type1_(type1) + , type2_(type2) + {} + + util::uuid const & uuid() const { return uuid_; } + std::type_info const & type1() const { return type1_; } + std::type_info const & type2() const { return type2_; } + + private: + util::uuid uuid_; + std::type_info const & type1_; + std::type_info const & type2_; + }; + struct component_registry { template void register_component() { - column_factories_.insert({Component::uuid(), []{ + auto const & uuid = Component::uuid(); + + if (auto it = types_.find(uuid); it != types_.end()) + { + if (it->second != &typeid(Component)) + throw duplicate_uuid_exception(uuid, *(it->second), typeid(Component)); + else + return; + } + + types_.insert({uuid, &typeid(Component)}); + + column_factories_.insert({uuid, []{ return std::make_unique>(); }}); } @@ -26,6 +60,7 @@ namespace psemek::ecs::detail } private: + util::hash_map types_; util::hash_map()>> column_factories_; };