diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 538a38e4c..b36cde141 100644 --- a/src/entt/entity/storage.hpp +++ b/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::operator[](pos); destruction.publish(*static_cast *>(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: diff --git a/test/entt/entity/group.cpp b/test/entt/entity/group.cpp index 5b18d7f54..a46e4f1cb 100644 --- a/test/entt/entity/group.cpp +++ b/test/entt/entity/group.cpp @@ -1284,6 +1284,24 @@ TEST(OwningGroup, PreventEarlyOptOut) { }); } +TEST(OwningGroup, SwappingValuesIsAllowed) { + entt::registry registry; + const auto group = registry.group(entt::get); + + for(std::size_t i{}; i < 2u; ++i) { + const auto entity = registry.create(); + registry.emplace(entity, static_cast(i)); + registry.emplace(entity); + } + + registry.destroy(group.back()); + + // thanks to @andranik3949 for pointing out this missing test + registry.view().each([](const auto entity, const auto &value) { + ASSERT_EQ(entt::to_integral(entity), value.value); + }); +} + TEST(OwningGroup, ExtendedGet) { using type = decltype(std::declval().group(entt::get).get({})); static_assert(std::tuple_size_v == 2u); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 59068ce86..6c33b150f 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1524,3 +1524,20 @@ TEST(Registry, Visit) { hasType[1] = false; } + +TEST(Registry, ScramblingPoolsIsAllowed) { + entt::registry registry; + registry.on_destroy().connect<&listener::sort>(); + + for(std::size_t i{}; i < 2u; ++i) { + const auto entity = registry.create(); + registry.emplace(entity, static_cast(i)); + } + + registry.destroy(registry.view().back()); + + // thanks to @andranik3949 for pointing out this missing test + registry.view().each([](const auto entity, const auto &value) { + ASSERT_EQ(entt::to_integral(entity), value); + }); +}