Procházet zdrojové kódy

storage (close #675):
* stable sigh_storage_mixin::swap_and_pop
* added tests to avoid regressions

Michele Caini před 5 roky
rodič
revize
785cd6bc11

+ 2 - 1
src/entt/entity/storage.hpp

@@ -653,7 +653,8 @@ class sigh_storage_mixin final: public Type {
         ENTT_ASSERT(ud != nullptr);
         const auto entity = basic_sparse_set<typename Type::entity_type>::operator[](pos);
         destruction.publish(*static_cast<basic_registry<typename Type::entity_type> *>(ud), entity);
-        Type::swap_and_pop(pos, ud);
+        // the position may have changed due to the actions of a listener
+        Type::swap_and_pop(this->index(entity), ud);
     }
 
 public:

+ 18 - 0
test/entt/entity/group.cpp

@@ -1284,6 +1284,24 @@ TEST(OwningGroup, PreventEarlyOptOut) {
     });
 }
 
+TEST(OwningGroup, SwappingValuesIsAllowed) {
+    entt::registry registry;
+    const auto group = registry.group<boxed_int>(entt::get<empty_type>);
+
+    for(std::size_t i{}; i < 2u; ++i) {
+        const auto entity = registry.create();
+        registry.emplace<boxed_int>(entity, static_cast<int>(i));
+        registry.emplace<empty_type>(entity);
+    }
+
+    registry.destroy(group.back());
+
+    // thanks to @andranik3949 for pointing out this missing test
+    registry.view<const boxed_int>().each([](const auto entity, const auto &value) {
+        ASSERT_EQ(entt::to_integral(entity), value.value);
+    });
+}
+
 TEST(OwningGroup, ExtendedGet) {
     using type = decltype(std::declval<entt::registry>().group<int, empty_type>(entt::get<char>).get({}));
     static_assert(std::tuple_size_v<type> == 2u);

+ 17 - 0
test/entt/entity/registry.cpp

@@ -1524,3 +1524,20 @@ TEST(Registry, Visit) {
 
     hasType[1] = false;
 }
+
+TEST(Registry, ScramblingPoolsIsAllowed) {
+    entt::registry registry;
+    registry.on_destroy<int>().connect<&listener::sort<int>>();
+
+    for(std::size_t i{}; i < 2u; ++i) {
+        const auto entity = registry.create();
+        registry.emplace<int>(entity, static_cast<int>(i));
+    }
+
+    registry.destroy(registry.view<int>().back());
+
+    // thanks to @andranik3949 for pointing out this missing test
+    registry.view<const int>().each([](const auto entity, const auto &value) {
+        ASSERT_EQ(entt::to_integral(entity), value);
+    });
+}