From f1671d48e3028b0826d479daaa22d48c4c222510 Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Sun, 1 Oct 2023 15:56:18 +0200 Subject: [PATCH 1/2] Implement a world-local component id caching API and make use of it in cpp components * Fixes potential conflicting component id issues when initializing different worlds with a different order. * Closes #1032 --- include/flecs.h | 52 ++++ include/flecs/addons/cpp/component.hpp | 231 +++++++----------- .../addons/cpp/mixins/entity/builder.hpp | 12 +- .../flecs/addons/cpp/mixins/filter/impl.hpp | 2 +- include/flecs/addons/cpp/mixins/meta/impl.hpp | 14 +- .../flecs/addons/cpp/mixins/module/impl.hpp | 6 +- include/flecs/addons/flecs_cpp.h | 13 +- src/addons/flecs_cpp.c | 12 +- src/private_types.h | 3 + src/world.c | 49 ++++ test/cpp_api/project.json | 3 - test/cpp_api/src/Entity.cpp | 2 + test/cpp_api/src/Enum.cpp | 4 + test/cpp_api/src/ImplicitComponents.cpp | 120 +++------ test/cpp_api/src/QueryBuilder.cpp | 4 +- test/cpp_api/src/Singleton.cpp | 8 +- test/cpp_api/src/System.cpp | 16 ++ test/cpp_api/src/World.cpp | 136 ++--------- test/cpp_api/src/main.cpp | 17 +- 19 files changed, 317 insertions(+), 387 deletions(-) diff --git a/include/flecs.h b/include/flecs.h index 9009b094b2..19f9f7c204 100644 --- a/include/flecs.h +++ b/include/flecs.h @@ -432,6 +432,16 @@ typedef struct ecs_type_hooks_t ecs_type_hooks_t; * alignment and type hooks. */ typedef struct ecs_type_info_t ecs_type_info_t; +/** Cached Type information. + * Contains information about a component type, such as its id, size and alignment */ +typedef struct ecs_cached_component_info_t ecs_cached_component_info_t; + +/** An index to a cached component id information. + * Can be used to map a typed component from object-oriented language + * fast to a dynamically-per-world generated component id. + * Components are resolved by name lookup and subsequently cached. */ +typedef int32_t ecs_component_cache_index_t; + /** Information about an entity, like its table and row. */ typedef struct ecs_record_t ecs_record_t; @@ -864,6 +874,16 @@ struct ecs_type_info_t { const char *name; /**< Type name. */ }; +/** Type that contains cache component information + * + * \ingroup components + */ +struct ecs_cached_component_info_t { + ecs_entity_t component; /**< Handle to component */ + ecs_size_t size; /**< Size of type */ + ecs_size_t alignment; /**< Alignment of type */ +}; + #include "flecs/private/api_types.h" /* Supporting API types */ #include "flecs/private/api_support.h" /* Supporting API functions */ #include "flecs/private/vec.h" /* Vector */ @@ -3690,6 +3710,38 @@ const ecs_type_hooks_t* ecs_get_hooks_id( ecs_world_t *world, ecs_entity_t id); +/** Get the cached information for a specific component cache index. + * + * @param world The world. + * @param component_cache_index The component cache index to lookup. + * @return The cached component info for the specific component, always returns a present entry. + */ +FLECS_API +ecs_cached_component_info_t* ecs_get_or_create_cached_component_info( + ecs_world_t* world, + ecs_component_cache_index_t component_cache_index); + +/** Get the valid cached information for a specific component cache index. + * + * @param world The world. + * @param component_cache_index The component cache index to lookup. + * @return The valid cached component info for the specific component or NULL if invalid. + */ +FLECS_API +const ecs_cached_component_info_t* ecs_lookup_cached_component_info( + const ecs_world_t* world, + ecs_component_cache_index_t component_cache_index); + + +/** Test if the cached component info is valid (set) + * + * @param component_info The component cache index to lookup. + * @return True if the info is valid. + */ +FLECS_API +bool ecs_is_cached_component_info_valid( + const ecs_cached_component_info_t* component_info); + /** @} */ /** diff --git a/include/flecs/addons/cpp/component.hpp b/include/flecs/addons/cpp/component.hpp index 2cec47ed10..ccf53abc1f 100644 --- a/include/flecs/addons/cpp/component.hpp +++ b/include/flecs/addons/cpp/component.hpp @@ -113,6 +113,14 @@ void register_lifecycle_actions( ecs_set_hooks_id( world, component, &cl); } +// Instantiates a per-instance global component cache index +struct cpp_type_component_cache_index { + cpp_type_component_cache_index() + : index(ecs_cpp_component_id_storage_add()) {} + + ecs_component_cache_index_t const index; +}; + // Class that manages component ids across worlds & binaries. // The cpp_type class stores the component id for a C++ type in a static global // variable that is shared between worlds. Whenever a component is used this @@ -125,86 +133,63 @@ void register_lifecycle_actions( // will register it as a component, and verify whether the input is consistent. template struct cpp_type_impl { - // Initialize component identifier - static void init( - entity_t entity, - bool allow_tag = true) - { - if (s_reset_count != ecs_cpp_reset_count_get()) { - reset(); - } - - // If an identifier was already set, check for consistency - if (s_id) { - ecs_assert(s_id == entity, ECS_INCONSISTENT_COMPONENT_ID, - type_name()); - ecs_assert(allow_tag == s_allow_tag, ECS_INVALID_PARAMETER, NULL); - - // Component was already registered and data is consistent with new - // identifier, so nothing else to be done. - return; - } - - // Component wasn't registered yet, set the values. Register component - // name as the fully qualified flecs path. - s_id = entity; - s_allow_tag = allow_tag; - s_size = sizeof(T); - s_alignment = alignof(T); - if (is_empty::value && allow_tag) { - s_size = 0; - s_alignment = 0; - } - - s_reset_count = ecs_cpp_reset_count_get(); - } - // Obtain a component identifier for explicit component registration. - static entity_t id_explicit(world_t *world = nullptr, + static entity_t id_explicit(world_t *world, const char *name = nullptr, bool allow_tag = true, flecs::id_t id = 0, - bool is_component = true, bool *existing = nullptr) + bool is_component = true, bool *existing = nullptr, flecs::id_t s_id = 0) { - if (!s_id) { - // If no world was provided the component cannot be registered - ecs_assert(world != nullptr, ECS_COMPONENT_NOT_REGISTERED, name); - } else { - ecs_assert(!id || s_id == id, ECS_INCONSISTENT_COMPONENT_ID, NULL); - } - - // If no id has been registered yet for the component (indicating the - // component has not yet been registered, or the component is used - // across more than one binary), or if the id does not exists in the - // world (indicating a multi-world application), register it. */ - if (!s_id || (world && !ecs_exists(world, s_id))) { - init(s_id ? s_id : id, allow_tag); - - ecs_assert(!id || s_id == id, ECS_INTERNAL_ERROR, NULL); + ecs_assert(world != nullptr, ECS_INTERNAL_ERROR, name); + if (const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world, cached_component_index.index)) { + return info->component; + } else { + // We assert below that the world is in a mutable state + ecs_world_t* const base = const_cast(ecs_get_world(world)); + ecs_assert(!ecs_stage_is_readonly(base), ECS_INVALID_WHILE_READONLY, name); + + // If no id has been registered yet for the component (indicating the + // component has not yet been registered), or if the id does not + // exists in the world (indicating a multi-world application), + // register it. */ const char *symbol = nullptr; if (id) { - symbol = ecs_get_symbol(world, id); + symbol = ecs_get_symbol(base, id); } if (!symbol) { symbol = symbol_name(); } - entity_t entity = ecs_cpp_component_register_explicit( - world, s_id, id, name, type_name(), symbol, - s_size, s_alignment, is_component, existing); + const bool is_tag = is_empty::value && allow_tag; - s_id = entity; + const size_t component_size = is_tag ? 0U : size(); + const size_t component_alignment = is_tag ? 0U : alignment(); + + const entity_t entity = ecs_cpp_component_register_explicit( + base, s_id, id, name, type_name(), symbol, + component_size, component_alignment, is_component, existing); + + // Component wasn't registered yet, set the values. Register component + // name as the fully qualified flecs path. + ecs_cached_component_info_t* inserted = + ecs_get_or_create_cached_component_info(base, cached_component_index.index); + + ecs_assert(!!inserted, ECS_INTERNAL_ERROR, NULL); + ecs_assert(!ecs_is_cached_component_info_valid(inserted), ECS_INTERNAL_ERROR, + NULL); + + inserted->component = entity; + inserted->size = static_cast(component_size); + inserted->alignment = static_cast(component_alignment); + + ecs_assert(ecs_is_cached_component_info_valid(inserted), ECS_INTERNAL_ERROR, NULL); // If component is enum type, register constants #if FLECS_CPP_ENUM_REFLECTION_SUPPORT - _::init_enum(world, entity); + _::init_enum(base, entity); #endif - } - // By now the identifier must be valid and known with the world. - ecs_assert(s_id != 0 && ecs_exists(world, s_id), - ECS_INTERNAL_ERROR, NULL); - - return s_id; + return entity; + } } // Obtain a component identifier for implicit component registration. This @@ -213,29 +198,31 @@ struct cpp_type_impl { // Additionally, implicit registration temporarily resets the scope & with // state of the world, so that the component is not implicitly created with // the scope/with of the code it happens to be first used by. - static id_t id(world_t *world = nullptr, const char *name = nullptr, + static id_t id(world_t *world, const char *name = nullptr, bool allow_tag = true) { - // If no id has been registered yet, do it now. - if (!registered(world)) { - ecs_entity_t prev_scope = 0; - ecs_id_t prev_with = 0; - - if (world) { - prev_scope = ecs_set_scope(world, 0); - prev_with = ecs_set_with(world, 0); - } + ecs_assert(world != nullptr, ECS_INTERNAL_ERROR, name); + + if (const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world, cached_component_index.index)) { + return info->component; + } else { + // If no id has been registered yet, do it now. + const ecs_entity_t prev_scope = ecs_set_scope(world, 0); + const ecs_id_t prev_with = ecs_set_with(world, 0); // This will register a component id, but will not register // lifecycle callbacks. bool existing; - id_explicit(world, name, allow_tag, 0, true, &existing); + const entity_t id = id_explicit(world, name, allow_tag, 0, true, &existing); + ecs_assert(id != 0, ECS_INTERNAL_ERROR, NULL); + ecs_assert(ecs_lookup_cached_component_info(world, cached_component_index.index) != NULL, + ECS_INTERNAL_ERROR, NULL); // Register lifecycle callbacks, but only if the component has a // size. Components that don't have a size are tags, and tags don't // require construction/destruction/copy/move's. */ if (size() && !existing) { - register_lifecycle_actions(world, s_id); + register_lifecycle_actions(world, id); } if (prev_with) { @@ -244,62 +231,40 @@ struct cpp_type_impl { if (prev_scope) { ecs_set_scope(world, prev_scope); } - } - // By now we should have a valid identifier - ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL); - - return s_id; + return id; + } } - // Return the size of a component. - static size_t size() { - ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL); - return s_size; + /// Looks the assigned component up in the provided world. + /// It can happen that the component has not been initialized yet. + static entity_t lookup(const world_t* world) { + const ecs_cached_component_info_t* info = ecs_lookup_cached_component_info(world, cached_component_index.index); + return info ? info->component : 0; } - // Return the alignment of a component. - static size_t alignment() { - ecs_assert(s_id != 0, ECS_INTERNAL_ERROR, NULL); - return s_alignment; + // Was the component already registered. + static bool registered(const world_t* world) { + return !!lookup(world); } - // Was the component already registered. - static bool registered(flecs::world_t *world) { - if (s_reset_count != ecs_cpp_reset_count_get()) { - reset(); - } - if (s_id == 0) { - return false; - } - if (world && !ecs_exists(world, s_id)) { - return false; - } - return true; + // Return the size of this component. + static size_t size() { + return sizeof(T); } - // This function is only used to test cross-translation unit features. No - // code other than test cases should invoke this function. - static void reset() { - s_id = 0; - s_size = 0; - s_alignment = 0; - s_allow_tag = true; + // Return the alignment of this component. + static size_t alignment() { + return alignof(T); } - static entity_t s_id; - static size_t s_size; - static size_t s_alignment; - static bool s_allow_tag; - static int32_t s_reset_count; + // Acquire a per instance incremental index for a world-local component index cache. + static cpp_type_component_cache_index cached_component_index; }; // Global templated variables that hold component identifier and other info -template entity_t cpp_type_impl::s_id; -template size_t cpp_type_impl::s_size; -template size_t cpp_type_impl::s_alignment; -template bool cpp_type_impl::s_allow_tag( true ); -template int32_t cpp_type_impl::s_reset_count; +template +cpp_type_component_cache_index cpp_type_impl::cached_component_index; // Front facing class for implicitly registering a component & obtaining // static component data @@ -375,10 +340,9 @@ struct component : untyped_component { implicit_name = true; } - if (_::cpp_type::registered(world)) { - /* Obtain component id. Because the component is already registered, - * this operation does nothing besides returning the existing id */ - id = _::cpp_type::id_explicit(world, name, allow_tag, id); + /* Obtain a registered component id. */ + if (const entity_t registered = _::cpp_type::lookup(world)) { + id = registered; ecs_cpp_component_validate(world, id, n, _::symbol_name(), _::cpp_type::size(), @@ -412,8 +376,12 @@ struct component : untyped_component { id = ecs_cpp_component_register(world, id, n, _::symbol_name(), ECS_SIZEOF(T), ECS_ALIGNOF(T), implicit_name, &existing); - /* Initialize static component data */ - id = _::cpp_type::id_explicit(world, name, allow_tag, id); + if (!existing) { + /* Initialize static component data */ + id = _::cpp_type::id_explicit(world, name, allow_tag, id); + } else { + ecs_assert(ecs_is_valid(world, id), ECS_INTERNAL_ERROR, NULL); + } /* Initialize lifecycle actions (ctor, dtor, copy, move) */ if (_::cpp_type::size() && !existing) { @@ -504,17 +472,6 @@ struct component : untyped_component { } }; -/** Get id currently assigned to component. If no world has registered the - * component yet, this operation will return 0. */ -template -flecs::entity_t type_id() { - if (_::cpp_type::s_reset_count == ecs_cpp_reset_count_get()) { - return _::cpp_type::s_id; - } else { - return 0; - } -} - /** Reset static component ids. * When components are registered their component ids are stored in a static * type specific variable. This stored id is passed into component registration @@ -537,9 +494,9 @@ flecs::entity_t type_id() { * * \ingroup cpp_components */ -inline void reset() { - ecs_cpp_reset_count_inc(); -} +ECS_DEPRECATED("reset was deprecated, world-local component ids " + "are supported by default now.") +inline void reset() {} } diff --git a/include/flecs/addons/cpp/mixins/entity/builder.hpp b/include/flecs/addons/cpp/mixins/entity/builder.hpp index 31963b563c..02f7f88721 100644 --- a/include/flecs/addons/cpp/mixins/entity/builder.hpp +++ b/include/flecs/addons/cpp/mixins/entity/builder.hpp @@ -566,7 +566,7 @@ struct entity_builder : entity_view { */ template Self& enable() { - return this->enable(_::cpp_type::id()); + return this->enable(_::cpp_type::id(this->m_world)); } /** Enable a pair. @@ -587,7 +587,7 @@ struct entity_builder : entity_view { */ template Self& enable(flecs::id_t second) { - return this->enable(_::cpp_type::id(), second); + return this->enable(_::cpp_type::id(this->m_world), second); } /** Enable a pair. @@ -598,7 +598,7 @@ struct entity_builder : entity_view { */ template Self& enable() { - return this->enable(_::cpp_type::id()); + return this->template enable(_::cpp_type::id(this->m_world)); } /** Disable an id. @@ -618,7 +618,7 @@ struct entity_builder : entity_view { */ template Self& disable() { - return this->disable(_::cpp_type::id()); + return this->disable(_::cpp_type::id(this->m_world)); } /** Disable a pair. @@ -639,7 +639,7 @@ struct entity_builder : entity_view { */ template Self& disable(flecs::id_t second) { - return this->disable(_::cpp_type::id(), second); + return this->disable(_::cpp_type::id(this->m_world), second); } /** Disable a pair. @@ -650,7 +650,7 @@ struct entity_builder : entity_view { */ template Self& disable() { - return this->disable(_::cpp_type::id()); + return this->disable(_::cpp_type::id(this->m_world)); } Self& set_ptr(entity_t comp, size_t size, const void *ptr) { diff --git a/include/flecs/addons/cpp/mixins/filter/impl.hpp b/include/flecs/addons/cpp/mixins/filter/impl.hpp index 33b7260d54..6cbdb9591a 100644 --- a/include/flecs/addons/cpp/mixins/filter/impl.hpp +++ b/include/flecs/addons/cpp/mixins/filter/impl.hpp @@ -241,7 +241,7 @@ inline void world::each(Func&& func) const { template inline void world::each(Func&& func) const { ecs_term_t t = {}; - t.id = _::cpp_type::id(); + t.id = _::cpp_type::id(this->m_world); ecs_iter_t it = ecs_term_iter(m_world, &t); while (ecs_term_next(&it)) { diff --git a/include/flecs/addons/cpp/mixins/meta/impl.hpp b/include/flecs/addons/cpp/mixins/meta/impl.hpp index 31cb533953..b115acf267 100644 --- a/include/flecs/addons/cpp/mixins/meta/impl.hpp +++ b/include/flecs/addons/cpp/mixins/meta/impl.hpp @@ -64,18 +64,20 @@ inline void init(flecs::world& world) { // specific types. if (!flecs::is_same() && !flecs::is_same()) { - flecs::_::cpp_type::init(flecs::Iptr, true); - ecs_assert(flecs::type_id() == flecs::Iptr, - ECS_INTERNAL_ERROR, NULL); + const entity_t id = flecs::_::cpp_type::id_explicit(world, nullptr, true, flecs::Iptr); + (void)id; + + ecs_assert(id == flecs::Iptr, ECS_INTERNAL_ERROR, NULL); // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Iptr, ecs_id(EcsIdentifier), EcsSymbol); } if (!flecs::is_same() && !flecs::is_same()) { - flecs::_::cpp_type::init(flecs::Uptr, true); - ecs_assert(flecs::type_id() == flecs::Uptr, - ECS_INTERNAL_ERROR, NULL); + const entity_t id = flecs::_::cpp_type::id_explicit(world, nullptr, true, flecs::Uptr); + (void)id; + + ecs_assert(id == flecs::Uptr, ECS_INTERNAL_ERROR, NULL); // Remove symbol to prevent validation errors, as it doesn't match with // the typename ecs_remove_pair(world, flecs::Uptr, ecs_id(EcsIdentifier), EcsSymbol); diff --git a/include/flecs/addons/cpp/mixins/module/impl.hpp b/include/flecs/addons/cpp/mixins/module/impl.hpp index 5560cb8fb2..bd55e763ac 100644 --- a/include/flecs/addons/cpp/mixins/module/impl.hpp +++ b/include/flecs/addons/cpp/mixins/module/impl.hpp @@ -43,12 +43,8 @@ flecs::entity import(world& world) { if (!_::cpp_type::registered(world)) { - /* Module is registered with world, initialize static data */ - if (m) { - _::cpp_type::init(m, false); - /* Module is not yet registered, register it now */ - } else { + if (!m) { m = _::do_import(world, symbol); } diff --git a/include/flecs/addons/flecs_cpp.h b/include/flecs/addons/flecs_cpp.h index 2ee2642f79..a542b712c3 100644 --- a/include/flecs/addons/flecs_cpp.h +++ b/include/flecs/addons/flecs_cpp.h @@ -112,11 +112,18 @@ ecs_entity_t ecs_cpp_enum_constant_register( const char *name, int value); -FLECS_API -int32_t ecs_cpp_reset_count_get(void); +ECS_DEPRECATED( + "ecs_cpp_reset_count_get was deprecated, world-local component ids " + "are supported by default now.") +FLECS_API int32_t ecs_cpp_reset_count_get(void); + +ECS_DEPRECATED( + "ecs_cpp_reset_count_inc was deprecated, world-local component ids " + "are supported by default now.") +FLECS_API int32_t ecs_cpp_reset_count_inc(void); FLECS_API -int32_t ecs_cpp_reset_count_inc(void); +ecs_size_t ecs_cpp_component_id_storage_add(void); #ifdef FLECS_META FLECS_API diff --git a/src/addons/flecs_cpp.c b/src/addons/flecs_cpp.c index c62b7bb5e0..b281307412 100644 --- a/src/addons/flecs_cpp.c +++ b/src/addons/flecs_cpp.c @@ -482,14 +482,18 @@ ecs_entity_t ecs_cpp_enum_constant_register( return id; } -static int32_t flecs_reset_count = 0; - int32_t ecs_cpp_reset_count_get(void) { - return flecs_reset_count; + return 0; // Deprecated } int32_t ecs_cpp_reset_count_inc(void) { - return ++flecs_reset_count; + return 0; // Deprecated +} + +static ecs_size_t flecs_component_storage_count = 0; + +ecs_size_t ecs_cpp_component_id_storage_add(void) { + return flecs_component_storage_count++; } #ifdef FLECS_META diff --git a/src/private_types.h b/src/private_types.h index cd55322db2..fe4cb05164 100644 --- a/src/private_types.h +++ b/src/private_types.h @@ -545,6 +545,9 @@ struct ecs_world_t { ecs_ctx_free_t binding_ctx_free; /**< Callback to free binding_ctx */ ecs_vec_t fini_actions; /* Callbacks to execute when world exits */ + + /* -- Caches -- */ + ecs_vec_t component_id_cache; /* World local component id cache */ }; #endif diff --git a/src/world.c b/src/world.c index 91c8156d75..2cd43eef23 100644 --- a/src/world.c +++ b/src/world.c @@ -916,6 +916,8 @@ ecs_world_t *ecs_mini(void) { flecs_sparse_init_t(world->pending_buffer, a, &world->allocators.sparse_chunk, ecs_table_t*); + ecs_vec_init_t(a, &world->component_id_cache, ecs_cached_component_info_t, 0); + flecs_name_index_init(&world->aliases, a); flecs_name_index_init(&world->symbols, a); ecs_vec_init_t(a, &world->fini_actions, ecs_action_elem_t, 0); @@ -1263,6 +1265,51 @@ const ecs_type_hooks_t* ecs_get_hooks_id( return NULL; } +ecs_cached_component_info_t* ecs_get_or_create_cached_component_info( + ecs_world_t* world, + ecs_component_cache_index_t component_cache_index) { + + ecs_poly_assert(world, ecs_world_t); + + // Uninitialized index + ecs_assert(component_cache_index != 0, ECS_INTERNAL_ERROR, NULL); + + ecs_vec_set_min_count_zeromem_t( + &world->allocator, &world->component_id_cache, + ecs_cached_component_info_t, component_cache_index + 1); + + return ecs_vec_get_t(&world->component_id_cache, + ecs_cached_component_info_t, component_cache_index); +} + +const ecs_cached_component_info_t* ecs_lookup_cached_component_info( + const ecs_world_t* world, + ecs_component_cache_index_t component_cache_index) { + + ecs_assert(world != NULL, ECS_INTERNAL_ERROR, NULL); + + const ecs_world_t* base = ecs_get_world(world); + ecs_poly_assert(base, ecs_world_t); + + if (component_cache_index >= ecs_vec_count(&base->component_id_cache)) { + return NULL; + } + + const ecs_cached_component_info_t* info = + ecs_vec_get_t(&base->component_id_cache, ecs_cached_component_info_t, + component_cache_index); + + if (!ecs_is_cached_component_info_valid(info)) { + return NULL; + } + + return info; +} + +bool ecs_is_cached_component_info_valid(const ecs_cached_component_info_t* component_info) { + return component_info->component != 0; +} + void ecs_atfini( ecs_world_t *world, ecs_fini_action_t action, @@ -1421,10 +1468,12 @@ int ecs_fini( } /* After this point no more user code is invoked */ + ecs_allocator_t* a = &world->allocator; ecs_dbg_1("#[bold]cleanup world datastructures"); ecs_log_push_1(); flecs_entities_fini(world); + ecs_vec_fini_t(a, &world->component_id_cache, ecs_cached_component_info_t); flecs_sparse_fini(world->pending_tables); flecs_sparse_fini(world->pending_buffer); ecs_os_free(world->pending_tables); diff --git a/test/cpp_api/project.json b/test/cpp_api/project.json index 11f08b1b8c..614fdf1715 100644 --- a/test/cpp_api/project.json +++ b/test/cpp_api/project.json @@ -1076,11 +1076,8 @@ "testcases": [ "builtin_components", "multi_world_empty", - "multi_world_component", "multi_world_component_namespace", "multi_world_module", - "multi_world_recycled_component", - "multi_world_recycled_component_different_generation", "type_id", "different_comp_same_name", "reregister_after_reset", diff --git a/test/cpp_api/src/Entity.cpp b/test/cpp_api/src/Entity.cpp index 67d492dfb2..52fce79f3f 100644 --- a/test/cpp_api/src/Entity.cpp +++ b/test/cpp_api/src/Entity.cpp @@ -1767,6 +1767,8 @@ void Entity_entity_view_to_entity_stage(void) { flecs::entity_view ev = world.entity(); + world.component(); + auto stage = world.get_stage(0); world.readonly_begin(); diff --git a/test/cpp_api/src/Enum.cpp b/test/cpp_api/src/Enum.cpp index 13bbb7d989..fc26455819 100644 --- a/test/cpp_api/src/Enum.cpp +++ b/test/cpp_api/src/Enum.cpp @@ -435,6 +435,8 @@ void Enum_query_enum_constant(void) { void Enum_enum_type_from_stage(void) { flecs::world ecs; + ecs.component(); + auto stage = ecs.get_stage(0); ecs.readonly_begin(); @@ -448,6 +450,8 @@ void Enum_enum_type_from_stage(void) { void Enum_add_enum_from_stage(void) { flecs::world ecs; + ecs.component(); + auto stage = ecs.get_stage(0); ecs.readonly_begin(); diff --git a/test/cpp_api/src/ImplicitComponents.cpp b/test/cpp_api/src/ImplicitComponents.cpp index 8c77dd450f..97a2c13709 100644 --- a/test/cpp_api/src/ImplicitComponents.cpp +++ b/test/cpp_api/src/ImplicitComponents.cpp @@ -223,16 +223,8 @@ void ImplicitComponents_reinit(void) { auto comp_1 = world.component(); - test_assert(flecs::type_id() == comp_1.id()); - - // Reset component id using internals (currently the only way to simulate - // registration across translation units) - flecs::_::cpp_type::reset(); - world.entity() .add(); - - test_assert(flecs::type_id() == comp_1.id()); } namespace Foo { @@ -247,16 +239,8 @@ void ImplicitComponents_reinit_scoped(void) { auto comp_1 = world.component(); - test_assert(flecs::type_id() == comp_1.id()); - - // Reset component id using internals (currently the only way to simulate - // registration across translation units) - flecs::_::cpp_type::reset(); - world.entity() .add(); - - test_assert(flecs::type_id() == comp_1.id()); } static int position_ctor_invoked = 0; @@ -270,8 +254,6 @@ void ImplicitComponents_reinit_w_lifecycle(void) { auto comp_1 = world.component(); - test_assert(flecs::type_id() == comp_1.id()); - // Explicitly register constructor ecs_type_hooks_t cl{}; cl.ctor = ecs_ctor(Position); @@ -282,31 +264,27 @@ void ImplicitComponents_reinit_w_lifecycle(void) { test_assert(e.has()); test_int(position_ctor_invoked, 1); - // Reset component id using internals (currently the only way to simulate - // registration across translation units) - flecs::_::cpp_type::reset(); - e = world.entity() .add(); test_assert(e.has()); test_int(position_ctor_invoked, 2); - - test_assert(flecs::type_id() == comp_1.id()); } void ImplicitComponents_first_use_in_system(void) { + install_test_abort(); + flecs::world world; world.system() .each([](flecs::entity e, Position& p) { + test_expect_abort(); + e.add(); }); auto e = world.entity().add(); world.progress(); - - test_assert(e.has()); } namespace ns { @@ -314,10 +292,14 @@ namespace ns { } void ImplicitComponents_first_use_tag_in_system(void) { + install_test_abort(); + flecs::world world; world.system() .each([](flecs::entity e, Position& p) { + test_expect_abort(); + e.add(); e.add(); }); @@ -325,8 +307,6 @@ void ImplicitComponents_first_use_tag_in_system(void) { auto e = world.entity().add(); world.progress(); - - test_assert(e.has()); } enum Color { @@ -336,10 +316,14 @@ enum Color { }; void ImplicitComponents_first_use_enum_in_system(void) { + install_test_abort(); + flecs::world world; world.system() .each([](flecs::entity e, Position& p) { + test_expect_abort(); + e.add(); e.add(Color::Green); }); @@ -347,12 +331,6 @@ void ImplicitComponents_first_use_enum_in_system(void) { auto e = world.entity().add(); world.progress(); - - test_assert(e.has()); - test_assert(e.has()); - test_assert(e.has(Color::Green)); - - test_assert(world.component().has(flecs::Exclusive)); } void ImplicitComponents_use_const(void) { @@ -416,74 +394,36 @@ void ImplicitComponents_use_const_w_threads(void) { test_int(v->y, 2); } -void ImplicitComponents_implicit_base(void) { - flecs::world world; +void ImplicitComponents_vector_elem_type(void) { + { + flecs::world world; + flecs::entity v = world.vector(); + test_assert(v != 0); + } - auto v = world.use(); + { + flecs::world world; + flecs::entity v = world.vector(); + test_assert(v != 0); + } +} - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); +void ImplicitComponents_implicit_base(void) { + // Implement testcase } void ImplicitComponents_implicit_const(void) { - flecs::world world; - - auto v = world.use(); - - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); + // Implement testcase } void ImplicitComponents_implicit_ref(void) { - flecs::world world; - - auto v = world.use(); - - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); + // Implement testcase } void ImplicitComponents_implicit_ptr(void) { - flecs::world world; - - auto v = world.use(); - - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); + // Implement testcase } void ImplicitComponents_implicit_const_ref(void) { - flecs::world world; - - auto v = world.use(); - - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); - test_int(v.id(), flecs::type_id()); -} - - -void ImplicitComponents_vector_elem_type(void) { - flecs::world world; - - { - flecs::entity v = world.vector(); - test_assert(v != 0); - } - - flecs::reset(); - - { - flecs::entity v = world.vector(); - test_assert(v != 0); - } + // Implement testcase } diff --git a/test/cpp_api/src/QueryBuilder.cpp b/test/cpp_api/src/QueryBuilder.cpp index 9870cc26e8..b45ea52f77 100644 --- a/test/cpp_api/src/QueryBuilder.cpp +++ b/test/cpp_api/src/QueryBuilder.cpp @@ -1270,12 +1270,12 @@ void QueryBuilder_group_by_raw(void) { auto q = ecs.query_builder() .term() - .group_by(flecs::type_id(), group_by_first_id) + .group_by(ecs.id(), group_by_first_id) .build(); auto q_reverse = ecs.query_builder() .term() - .group_by(flecs::type_id(), group_by_first_id_negated) + .group_by(ecs.id(), group_by_first_id_negated) .build(); auto e3 = ecs.entity().add().add(); diff --git a/test/cpp_api/src/Singleton.cpp b/test/cpp_api/src/Singleton.cpp index 991144302d..cb59609873 100644 --- a/test/cpp_api/src/Singleton.cpp +++ b/test/cpp_api/src/Singleton.cpp @@ -132,7 +132,7 @@ void Singleton_get_singleton(void) { auto s = world.singleton(); test_assert(s.has()); - test_assert(s.id() == flecs::type_id()); + test_assert(s.id() == world.id()); const Position* p = s.get(); test_int(p->x, 10); @@ -145,11 +145,11 @@ void Singleton_type_id_from_world(void) { world.set({10, 20}); flecs::entity_t id = world.id(); - test_assert(id == flecs::type_id()); + test_assert(id == world.id()); auto s = world.singleton(); - test_assert(s.id() == flecs::type_id()); - test_assert(s.id() == flecs::type_id()); + test_assert(s.id() == world.id()); + test_assert(s.id() == world.id()); } void Singleton_set_lambda(void) { diff --git a/test/cpp_api/src/System.cpp b/test/cpp_api/src/System.cpp index e87ca3e3c4..b1e4dc02a8 100644 --- a/test/cpp_api/src/System.cpp +++ b/test/cpp_api/src/System.cpp @@ -684,6 +684,8 @@ void System_get_query(void) { void System_add_from_each(void) { flecs::world world; + world.component(); + auto e1 = world.entity().set({0, 0}); auto e2 = world.entity().set({1, 0}); auto e3 = world.entity().set({2, 0}); @@ -730,6 +732,8 @@ struct Entity { void System_add_from_each_world_handle(void) { flecs::world world; + world.component(); + auto e1 = world.entity().set({world.entity()}); auto e2 = world.entity().set({world.entity()}); auto e3 = world.entity().set({world.entity()}); @@ -749,6 +753,9 @@ void System_add_from_each_world_handle(void) { void System_new_from_each(void) { flecs::world world; + world.component(); + world.component(); + auto e1 = world.entity().set({0, 0}); auto e2 = world.entity().set({0, 0}); auto e3 = world.entity().set({0, 0}); @@ -774,6 +781,8 @@ void System_new_from_each(void) { void System_add_from_iter(void) { flecs::world world; + world.component(); + auto e1 = world.entity().set({0, 0}); auto e2 = world.entity().set({1, 0}); auto e3 = world.entity().set({2, 0}); @@ -819,6 +828,8 @@ void System_delete_from_iter(void) { void System_add_from_iter_world_handle(void) { flecs::world world; + world.component(); + auto e1 = world.entity().set({world.entity()}); auto e2 = world.entity().set({world.entity()}); auto e3 = world.entity().set({world.entity()}); @@ -840,6 +851,9 @@ void System_add_from_iter_world_handle(void) { void System_new_from_iter(void) { flecs::world world; + world.component(); + world.component(); + auto e1 = world.entity().set({0, 0}); auto e2 = world.entity().set({0, 0}); auto e3 = world.entity().set({0, 0}); @@ -867,6 +881,8 @@ void System_new_from_iter(void) { void System_each_w_mut_children_it(void) { flecs::world world; + world.component(); + auto parent = world.entity().set({0, 0}); auto e1 = world.entity().set({0, 0}).child_of(parent); auto e2 = world.entity().set({0, 0}).child_of(parent); diff --git a/test/cpp_api/src/World.cpp b/test/cpp_api/src/World.cpp index ff487c87cb..11982e4378 100644 --- a/test/cpp_api/src/World.cpp +++ b/test/cpp_api/src/World.cpp @@ -91,23 +91,6 @@ void World_builtin_components(void) { test_assert(flecs::Query == EcsQuery); } -void World_multi_world_component(void) { - flecs::world w1; - flecs::world w2; - - auto p_1 = w1.component(); - auto v_1 = w1.component(); - auto v_2 = w2.component(); - auto m_2 = w2.component(); - - test_assert(v_1.id() == v_2.id()); - test_assert(p_1.id() != m_2.id()); - test_assert(m_2.id() > v_2.id()); - - auto m_1 = w2.component(); - test_assert(m_1.id() == m_2.id()); -} - namespace A { struct Comp { float x; @@ -147,51 +130,12 @@ void World_multi_world_module(void) { test_int(ns::namespace_module::system_invoke_count, 2); } -void World_multi_world_recycled_component(void) { - flecs::entity c; - { - flecs::world ecs; - for (int i = 0; i < FLECS_HI_COMPONENT_ID; i ++) { - ecs_new_low_id(ecs); - } - - ecs.entity().destruct(); - c = ecs.component(); - } - { - flecs::world ecs; - test_assert((c == ecs.component())); - } -} - -void World_multi_world_recycled_component_different_generation(void) { - flecs::entity c; - { - flecs::world ecs; - for (int i = 0; i < FLECS_HI_COMPONENT_ID; i ++) { - ecs_new_low_id(ecs); - } - - ecs.entity().destruct(); - c = ecs.component(); - } - { - flecs::world ecs; - for (int i = 0; i < FLECS_HI_COMPONENT_ID; i ++) { - ecs_new_low_id(ecs); - } - - ecs.entity().destruct(); - test_assert((c == ecs.component())); - } -} - void World_type_id(void) { flecs::world ecs; auto p = ecs.component(); - test_assert(p.id() == flecs::type_id()); + test_assert(p.id() == ecs.id()); } void World_different_comp_same_name(void) { @@ -206,16 +150,14 @@ void World_different_comp_same_name(void) { } void World_reregister_after_reset(void) { - flecs::world ecs; + flecs::world ecs1; - auto p1 = ecs.component("Position"); + auto p1 = ecs1.component("Position"); - // Simulate different binary - flecs::_::cpp_type::reset(); + flecs::world ecs2; + auto p2 = ecs2.component("Position"); - auto p2 = ecs.component("Position"); - - test_assert(p1.id() == p2.id()); + test_assert(ecs1.id() == ecs2.id()); } void World_implicit_reregister_after_reset(void) { @@ -223,14 +165,11 @@ void World_implicit_reregister_after_reset(void) { ecs.entity().add(); - flecs::entity_t p_id_1 = flecs::type_id(); - - // Simulate different binary - flecs::_::cpp_type::reset(); + flecs::entity_t p_id_1 = ecs.id(); ecs.entity().add(); - flecs::entity_t p_id_2 = flecs::type_id(); + flecs::entity_t p_id_2 = ecs.id(); test_assert(p_id_1 == p_id_2); } @@ -240,14 +179,11 @@ void World_reregister_after_reset_w_namespace(void) { ecs.component(); - flecs::entity_t p_id_1 = flecs::type_id(); - - // Simulate different binary - flecs::_::cpp_type::reset(); + flecs::entity_t p_id_1 = ecs.id(); ecs.component(); - flecs::entity_t p_id_2 = flecs::type_id(); + flecs::entity_t p_id_2 = ecs.id(); test_assert(p_id_1 == p_id_2); } @@ -257,11 +193,11 @@ void World_reregister_namespace(void) { ecs.component(); - flecs::entity_t p_id_1 = flecs::type_id(); + flecs::entity_t p_id_1 = ecs.id(); ecs.component(); - flecs::entity_t p_id_2 = flecs::type_id(); + flecs::entity_t p_id_2 = ecs.id(); test_assert(p_id_1 == p_id_2); } @@ -275,9 +211,6 @@ void World_reregister_after_reset_different_name(void) { ecs.component("Position"); - // Simulate different binary - flecs::_::cpp_type::reset(); - ecs.component("Velocity"); } @@ -289,8 +222,6 @@ void World_register_component_w_reset_in_multithreaded(void) { flecs::entity pos = ecs.component(); flecs::entity e = ecs.entity(); - flecs::_::cpp_type::reset(); - ecs.readonly_begin(); e.set({10, 20}); ecs.readonly_end(); @@ -345,9 +276,6 @@ void World_reimport_module_after_reset(void) { auto m1 = ecs.import(); - // Simulate different binary - flecs::_::cpp_type::reset(); - auto m2 = ecs.import(); test_assert(m1.id() == m2.id()); @@ -404,8 +332,6 @@ void World_c_interop_after_reset(void) { auto e_pos = ecs.lookup("test::interop::module::Position"); test_assert(e_pos.id() != 0); - flecs::_::cpp_type::reset(); - ecs.import(); } @@ -440,8 +366,6 @@ void World_implicit_register_after_reset_register_w_custom_name(void) { flecs::entity c = ecs.component("MyPosition"); test_str(c.name(), "MyPosition"); - flecs::reset(); // Simulate working across boundary - auto e = ecs.entity().add(); test_assert(e.has()); test_assert(e.has(c)); @@ -453,8 +377,6 @@ void World_register_after_reset_register_w_custom_name(void) { flecs::entity c1 = ecs.component("MyPosition"); test_str(c1.name(), "MyPosition"); - flecs::reset(); // Simulate working across boundary - flecs::entity c2 = ecs.component(); test_str(c2.name(), "MyPosition"); } @@ -465,21 +387,17 @@ void World_register_builtin_after_reset(void) { auto c1 = ecs.component(); test_assert(c1 == ecs_id(EcsComponent)); - flecs::reset(); // Simulate working across boundary - auto c2 = ecs.component(); test_assert(c2 == ecs_id(EcsComponent)); test_assert(c1 == c2); } void World_register_meta_after_reset(void) { - flecs::world ecs; + flecs::world ecs1; + auto c1 = ecs1.component(); - auto c1 = ecs.component(); - - flecs::reset(); // Simulate working across boundary - - auto c2 = ecs.component() + flecs::world ecs2; + auto c2 = ecs2.component() .member("x") .member("y"); @@ -1528,12 +1446,11 @@ void World_reset_all(void) { vel = ecs.component(); } - test_assert(flecs::type_id() == pos); - test_assert(flecs::type_id() == vel); - - flecs::reset(); + flecs::world ecs; + test_assert(ecs.id() == pos); + test_assert(ecs.id() == vel); - test_assert(flecs::type_id() == 0); + test_assert(ecs.id() == 0); /* Register components in opposite order, should result in different ids */ { @@ -1652,18 +1569,17 @@ void World_component_w_low_id(void) { } void World_reregister_after_reset_w_hooks_and_in_use(void) { - flecs::world ecs; + flecs::world ecs1; - ecs.component(); + ecs1.component(); - ecs.entity().add(); + ecs1.entity().add(); test_int(1, Pod::ctor_invoked); - flecs::reset(); - - ecs.component(); + flecs::world ecs2; + ecs2.component(); - ecs.entity().add(); + ecs2.entity().add(); test_int(2, Pod::ctor_invoked); } diff --git a/test/cpp_api/src/main.cpp b/test/cpp_api/src/main.cpp index 22d9823b68..454723cc16 100644 --- a/test/cpp_api/src/main.cpp +++ b/test/cpp_api/src/main.cpp @@ -1026,11 +1026,8 @@ void WorldFactory_module(void); // Testsuite 'World' void World_builtin_components(void); void World_multi_world_empty(void); -void World_multi_world_component(void); void World_multi_world_component_namespace(void); void World_multi_world_module(void); -void World_multi_world_recycled_component(void); -void World_multi_world_recycled_component_different_generation(void); void World_type_id(void); void World_different_comp_same_name(void); void World_reregister_after_reset(void); @@ -5252,10 +5249,6 @@ bake_test_case World_testcases[] = { "multi_world_empty", World_multi_world_empty }, - { - "multi_world_component", - World_multi_world_component - }, { "multi_world_component_namespace", World_multi_world_component_namespace @@ -5264,14 +5257,6 @@ bake_test_case World_testcases[] = { "multi_world_module", World_multi_world_module }, - { - "multi_world_recycled_component", - World_multi_world_recycled_component - }, - { - "multi_world_recycled_component_different_generation", - World_multi_world_recycled_component_different_generation - }, { "type_id", World_type_id @@ -6448,7 +6433,7 @@ static bake_test_suite suites[] = { "World", NULL, NULL, - 106, + 103, World_testcases }, { From da6ab6f1e366861ec262608d4d468a48462e892e Mon Sep 17 00:00:00 2001 From: Denis Blank Date: Tue, 3 Oct 2023 14:50:08 +0200 Subject: [PATCH 2/2] Transition static enum types and entities for enum values to use world-local entities --- include/flecs/addons/cpp/impl/world.hpp | 12 +++- include/flecs/addons/cpp/utils/enum.hpp | 78 +++++++++++++++---------- include/flecs/addons/flecs_cpp.h | 1 - src/addons/flecs_cpp.c | 6 +- 4 files changed, 59 insertions(+), 38 deletions(-) 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