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

entity: make to_entity work with stable types - close #1233

Michele Caini 11 месяцев назад
Родитель
Сommit
4208eaa4d8
2 измененных файлов с 18 добавлено и 5 удалено
  1. 4 4
      src/entt/entity/helper.hpp
  2. 14 1
      test/entt/entity/helper.cpp

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

@@ -127,11 +127,11 @@ typename basic_storage<Args...>::entity_type to_entity(const basic_storage<Args.
     using traits_type = component_traits<typename basic_storage<Args...>::value_type, typename basic_storage<Args...>::entity_type>;
     static_assert(traits_type::page_size != 0u, "Unexpected page size");
     const typename basic_storage<Args...>::base_type &base = storage;
-    const auto *addr = std::addressof(instance);
+    const auto *page = storage.raw();
 
-    for(auto it = base.rbegin(), last = base.rend(); it < last; it += traits_type::page_size) {
-        if(const auto dist = (addr - std::addressof(storage.get(*it))); dist >= 0 && dist < static_cast<decltype(dist)>(traits_type::page_size)) {
-            return *(it + dist);
+    for(std::size_t pos{}, count = storage.size(); pos < count; pos += traits_type::page_size, ++page) {
+        if(const auto dist = (std::addressof(instance) - *page); dist >= 0 && dist < static_cast<decltype(dist)>(traits_type::page_size)) {
+            return *(base.rbegin() + static_cast<decltype(dist)>(pos) + dist);
         }
     }
 

+ 14 - 1
test/entt/entity/helper.cpp

@@ -96,7 +96,8 @@ TYPED_TEST(ToEntity, Functionalities) {
     ASSERT_EQ(*storage.entt::sparse_set::rbegin(), entity);
     ASSERT_EQ(&*(storage.rbegin() + traits_type::page_size - (1u + traits_type::in_place_delete)), &storage.get(other));
 
-    registry.destroy(other);
+    // erase in the middle
+    storage.erase(other);
 
     ASSERT_EQ(entt::to_entity(storage, storage.get(entity)), entity);
     ASSERT_EQ(entt::to_entity(storage, storage.get(next)), next);
@@ -105,6 +106,18 @@ TYPED_TEST(ToEntity, Functionalities) {
     ASSERT_EQ(&*(storage.rbegin() + traits_type::page_size - 1u), &storage.get(next));
 
     ASSERT_EQ(entt::to_entity(storage, value), null);
+
+    storage.clear();
+
+    storage.emplace(entity);
+    storage.emplace(other);
+    storage.emplace(next);
+
+    // erase first
+    storage.erase(entity);
+
+    ASSERT_EQ(entt::to_entity(storage, value), null);
+    ASSERT_EQ(entt::to_entity(storage, storage.get(other)), other);
 }
 
 TEST(SighHelper, Functionalities) {