Просмотр исходного кода

helper: make to_entity also work for stable types (close #768)

Michele Caini 4 лет назад
Родитель
Сommit
5b8dcff2a4

+ 4 - 3
src/entt/entity/helper.hpp

@@ -138,11 +138,12 @@ void invoke(basic_registry<Entity> &reg, const Entity entt) {
  */
 template<typename Entity, typename Component>
 Entity to_entity(const basic_registry<Entity> &reg, const Component &instance) {
-    const auto view = reg.template view<const Component>();
+    const auto &storage = reg.template storage<const Component>();
+    const typename std::remove_const_t<std::remove_reference_t<decltype(storage)>>::base_type &base = storage;
     const auto *addr = std::addressof(instance);
 
-    for(auto it = view.rbegin(), last = view.rend(); it < last; it += ENTT_PACKED_PAGE) {
-        if(const auto dist = (addr - std::addressof(view.template get<const Component>(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
+    for(auto it = base.rbegin(), last = base.rend(); it < last; it += ENTT_PACKED_PAGE) {
+        if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < ENTT_PACKED_PAGE) {
             return *(it + dist);
         }
     }

+ 47 - 0
test/entt/entity/helper.cpp

@@ -13,6 +13,15 @@ struct clazz {
     entt::entity entt{entt::null};
 };
 
+struct stable_type {
+    int value;
+};
+
+template<>
+struct entt::component_traits<stable_type>: basic_component_traits {
+    using in_place_delete = std::true_type;
+};
+
 TEST(Helper, AsView) {
     entt::registry registry;
     const entt::registry cregistry;
@@ -79,3 +88,41 @@ TEST(Helper, ToEntity) {
     ASSERT_EQ(entt::to_entity(registry, 42), null);
     ASSERT_EQ(entt::to_entity(registry, value), null);
 }
+
+TEST(Helper, ToEntityStableType) {
+    entt::registry registry;
+    const entt::entity null = entt::null;
+    const stable_type value{42};
+
+    ASSERT_EQ(entt::to_entity(registry, stable_type{42}), null);
+    ASSERT_EQ(entt::to_entity(registry, value), null);
+
+    const auto entity = registry.create();
+    registry.emplace<stable_type>(entity);
+
+    while(registry.size<stable_type>() < (ENTT_PACKED_PAGE - 2u)) {
+        registry.emplace<stable_type>(registry.create(), value);
+    }
+
+    const auto other = registry.create();
+    const auto next = registry.create();
+
+    registry.emplace<stable_type>(other);
+    registry.emplace<stable_type>(next);
+
+    ASSERT_EQ(entt::to_entity(registry, registry.get<stable_type>(entity)), entity);
+    ASSERT_EQ(entt::to_entity(registry, registry.get<stable_type>(other)), other);
+    ASSERT_EQ(entt::to_entity(registry, registry.get<stable_type>(next)), next);
+
+    ASSERT_EQ(&registry.get<stable_type>(entity) + ENTT_PACKED_PAGE - 2u, &registry.get<stable_type>(other));
+
+    registry.destroy(other);
+
+    ASSERT_EQ(entt::to_entity(registry, registry.get<stable_type>(entity)), entity);
+    ASSERT_EQ(entt::to_entity(registry, registry.get<stable_type>(next)), next);
+
+    ASSERT_EQ(&registry.get<stable_type>(entity) + ENTT_PACKED_PAGE - 1u, &registry.get<stable_type>(next));
+
+    ASSERT_EQ(entt::to_entity(registry, stable_type{42}), null);
+    ASSERT_EQ(entt::to_entity(registry, value), null);
+}

+ 1 - 1
test/lib/registry/lib.cpp

@@ -11,7 +11,7 @@ ENTT_API void update_position(entt::registry &registry) {
 
 ENTT_API void emplace_velocity(entt::registry &registry) {
     // forces the creation of the pool for the velocity component
-    registry.storage<velocity>();
+    static_cast<void>(registry.storage<velocity>());
 
     for(auto entity: registry.view<position>()) {
         registry.emplace<velocity>(entity, 1., 1.);

+ 1 - 1
test/lib/registry_plugin/plugin.cpp

@@ -9,7 +9,7 @@ CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
         auto &registry = *static_cast<entt::registry *>(ctx->userdata);
 
         // forces the creation of the pool for the velocity component
-        registry.storage<velocity>();
+        static_cast<void>(registry.storage<velocity>());
 
         const auto view = registry.view<position>();
         registry.insert(view.begin(), view.end(), velocity{1., 1.});