Track uuid->type mapping for ecs components and throw an exception when the same uuid is used for different components

This commit is contained in:
Nikita Lisitsa 2024-05-21 13:38:05 +03:00
parent 6591dd1893
commit eab13e2ae5

View file

@ -4,16 +4,50 @@
#include <psemek/util/uuid.hpp>
#include <psemek/util/hash_table.hpp>
#include <psemek/util/function.hpp>
#include <psemek/util/exception.hpp>
#include <psemek/util/to_string.hpp>
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 <typename Component>
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<column_impl<Component>>();
}});
}
@ -26,6 +60,7 @@ namespace psemek::ecs::detail
}
private:
util::hash_map<util::uuid, std::type_info const *> types_;
util::hash_map<util::uuid, util::function<std::unique_ptr<column>()>> column_factories_;
};