diff --git a/include/flecs/addons/cpp/impl/world.hpp b/include/flecs/addons/cpp/impl/world.hpp index f0fa16da4d..9e5e8b01e9 100644 --- a/include/flecs/addons/cpp/impl/world.hpp +++ b/include/flecs/addons/cpp/impl/world.hpp @@ -254,17 +254,23 @@ inline flecs::entity world::ensure(flecs::entity_t e) const { template inline flecs::entity enum_data::entity() const { - return flecs::entity(world_, impl_.id); + return flecs::entity(world_, _::cpp_type::id_explicit(world_)); } template inline flecs::entity enum_data::entity(int value) const { - return flecs::entity(world_, impl_.constants[value].id); + ecs_component_cache_index_t const index = impl_.constants[value].index; + if (index == 0) { + return flecs::entity(); + } + + const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world_, index); + return info ? flecs::entity(world_, info->component) : flecs::entity(); } template inline flecs::entity enum_data::entity(E value) const { - return flecs::entity(world_, impl_.constants[static_cast(value)].id); + return entity(static_cast(value)); } /** Use provided scope for operations ran on returned world. diff --git a/include/flecs/addons/cpp/utils/enum.hpp b/include/flecs/addons/cpp/utils/enum.hpp index 462687df4b..d97bc8df6a 100644 --- a/include/flecs/addons/cpp/utils/enum.hpp +++ b/include/flecs/addons/cpp/utils/enum.hpp @@ -151,46 +151,65 @@ static const char* enum_constant_to_name() { /** Enumeration constant data */ struct enum_constant_data { - flecs::entity_t id; + ecs_component_cache_index_t index = 0; + int value; int next; + char const* name; }; /** Enumeration type data */ struct enum_data_impl { - flecs::entity_t id; - int min; - int max; + int min = FLECS_ENUM_MAX(int); + int max = 0; enum_constant_data constants[FLECS_ENUM_MAX_COUNT]; }; /** Class that scans an enum for constants, extracts names & creates entities */ template struct enum_type { - static enum_data_impl data; + enum_data_impl data; - static enum_type& get() { + static enum_type const& get() { static _::enum_type instance; return instance; } - flecs::entity_t entity(E value) const { - return data.constants[static_cast(value)].id; + flecs::entity_t entity(flecs::world_t* world, E value) const { + const ecs_component_cache_index_t index = data.constants[static_cast(value)].index; + const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world, index); + return info ? info->component : 0; } - void init(flecs::world_t *world, flecs::entity_t id) { + void init(flecs::world_t *world, flecs::entity_t id) const { #if !FLECS_CPP_ENUM_REFLECTION_SUPPORT ecs_abort(ECS_UNSUPPORTED, "enum reflection requires gcc 7.5 or higher") #endif ecs_log_push(); ecs_cpp_enum_init(world, id); - data.id = id; - data.min = FLECS_ENUM_MAX(int); - init< enum_last::value >(world); + + for (const enum_constant_data& constant : data.constants) { + if (!constant.index) { + continue; + } + + ecs_cached_component_info_t* info = ecs_get_or_create_cached_component_info(world, constant.index); + if (ecs_is_cached_component_info_valid(info)) { + // Do nothing if initialized already + continue; + } + + info->component = ecs_cpp_enum_constant_register(world, id, constant.name, constant.value); + } + ecs_log_pop(); } private: + enum_type() { + init(); + } + template static constexpr int to_int() { return static_cast(Value); @@ -207,34 +226,33 @@ struct enum_type { } template () > = 0> - static void init_constant(flecs::world_t*) { } + void init_constant() { } template () > = 0> - static void init_constant(flecs::world_t *world) { - int v = to_int(); - const char *name = enum_constant_to_name(); - data.constants[v].next = data.min; + void init_constant() { + int const v = to_int(); + + enum_constant_data &constant = data.constants[v]; + constant.value = v; + constant.index = ecs_cpp_component_id_storage_add(); + constant.next = data.min; + constant.name = enum_constant_to_name(); + data.min = v; if (!data.max) { data.max = v; } - - data.constants[v].id = ecs_cpp_enum_constant_register( - world, data.id, data.constants[v].id, name, v); } template - static void init(flecs::world_t *world) { - init_constant(world); + void init() { + init_constant(); if (is_not_0()) { - init() - is_not_0()>()>(world); + init() - is_not_0()>()>(); } } }; -template -enum_data_impl enum_type::data; - template ::value > = 0> inline static void init_enum(flecs::world_t *world, flecs::entity_t id) { _::enum_type::get().init(world, id); @@ -248,12 +266,12 @@ inline static void init_enum(flecs::world_t*, flecs::entity_t) { } /** Enumeration type data wrapper with world pointer */ template struct enum_data { - enum_data(flecs::world_t *world, _::enum_data_impl& impl) + enum_data(flecs::world_t *world, _::enum_data_impl const& impl) : world_(world) , impl_(impl) { } - bool is_valid(int value) { - return impl_.constants[value].id != 0; + bool is_valid(int value) const { + return impl_.constants[value].index != 0; } int first() const { @@ -273,7 +291,7 @@ struct enum_data { flecs::entity entity(E value) const; flecs::world_t *world_; - _::enum_data_impl& impl_; + _::enum_data_impl const& impl_; }; /** Convenience function for getting enum reflection data */ diff --git a/include/flecs/addons/flecs_cpp.h b/include/flecs/addons/flecs_cpp.h index a542b712c3..b24f48d5b6 100644 --- a/include/flecs/addons/flecs_cpp.h +++ b/include/flecs/addons/flecs_cpp.h @@ -108,7 +108,6 @@ FLECS_API ecs_entity_t ecs_cpp_enum_constant_register( ecs_world_t *world, ecs_entity_t parent, - ecs_entity_t id, const char *name, int value); diff --git a/src/addons/flecs_cpp.c b/src/addons/flecs_cpp.c index b281307412..b5a245dcbf 100644 --- a/src/addons/flecs_cpp.c +++ b/src/addons/flecs_cpp.c @@ -438,7 +438,6 @@ void ecs_cpp_enum_init( ecs_entity_t ecs_cpp_enum_constant_register( ecs_world_t *world, ecs_entity_t parent, - ecs_entity_t id, const char *name, int value) { @@ -455,8 +454,7 @@ ecs_entity_t ecs_cpp_enum_constant_register( } ecs_entity_t prev = ecs_set_scope(world, parent); - id = ecs_entity(world, { - .id = id, + ecs_entity_t id = ecs_entity(world, { .name = name }); ecs_assert(id != 0, ECS_INVALID_OPERATION, name); @@ -493,7 +491,7 @@ int32_t ecs_cpp_reset_count_inc(void) { static ecs_size_t flecs_component_storage_count = 0; ecs_size_t ecs_cpp_component_id_storage_add(void) { - return flecs_component_storage_count++; + return ++flecs_component_storage_count; } #ifdef FLECS_META