diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 865416da5..0ded677b4 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -45,13 +45,14 @@ template class basic_registry { using traits_type = entt_traits; using poly_storage_type = typename poly_storage_traits::storage_type; + using basic_common_type = basic_sparse_set; template using storage_type = constness_as_t>::storage_type, Component>; struct pool_data { poly_storage_type poly; - std::unique_ptr> pool{}; + std::unique_ptr pool{}; }; template @@ -61,7 +62,7 @@ class basic_registry { struct group_handler, get_t, Owned...> { static_assert(!std::disjunction_v::in_place_delete...>, "Groups do not support in-place delete"); static_assert(std::conjunction_v>..., std::is_same>..., std::is_same>...>, "One or more component types are invalid"); - std::conditional_t, std::size_t> current{}; + std::conditional_t current{}; template void maybe_valid_if(basic_registry &owner, const Entity entt) { @@ -140,10 +141,10 @@ class basic_registry { } auto release_entity(const Entity entity, const typename traits_type::version_type version) { - const auto entt = traits_type::to_entity(entity); - entities[entt] = traits_type::construct(traits_type::to_entity(free_list), version + (version == traits_type::to_version(tombstone))); + const auto vers = version + (version == traits_type::to_version(tombstone)); + entities[traits_type::to_entity(entity)] = traits_type::construct(traits_type::to_entity(free_list), vers); free_list = (tombstone | entity); - return traits_type::to_version(entities[entt]); + return vers; } public: @@ -562,8 +563,8 @@ public: version_type destroy(const entity_type entity, const version_type version) { ENTT_ASSERT(valid(entity), "Invalid entity"); - for(auto pos = pools.size(); pos; --pos) { - pools[pos-1].pool && pools[pos-1].pool->remove(entity, this); + for(auto &&pdata: pools) { + pdata.pool && pdata.pool->remove(entity, this); } return release_entity(entity, version); @@ -580,8 +581,16 @@ public: */ template void destroy(It first, It last) { - for(; first != last; ++first) { - destroy(*first, version(*first) + 1u); + if constexpr(is_iterator_type_v) { + for(; first != last; ++first) { + destroy(*first, version(*first) + 1u); + } + } else { + for(auto &&pdata: pools) { + pdata.pool && pdata.pool->remove(first, last, this); + } + + release(first, last); } } @@ -756,10 +765,19 @@ public: */ template size_type remove(It first, It last) { + static_assert(sizeof...(Component) > 0, "Provide one or more component types"); + const auto cpools = std::make_tuple(assure()...); size_type count{}; - for(; first != last; ++first) { - count += remove(*first); + if constexpr(is_iterator_type_v) { + for(; first != last; ++first) { + const auto entity = *first; + ENTT_ASSERT(valid(entity), "Invalid entity"); + count += (std::get *>(cpools)->remove(entity, this) + ...); + } + } else { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity"); + count += (std::get *>(cpools)->remove(first, last, this) + ...); } return count; @@ -794,8 +812,18 @@ public: */ template void erase(It first, It last) { - for(; first != last; ++first) { - erase(*first); + static_assert(sizeof...(Component) > 0, "Provide one or more component types"); + const auto cpools = std::make_tuple(assure()...); + + if constexpr(is_iterator_type_v) { + for(; first != last; ++first) { + const auto entity = *first; + ENTT_ASSERT(valid(entity), "Invalid entity"); + (std::get *>(cpools)->erase(entity, this), ...); + } + } else { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity"); + (std::get *>(cpools)->erase(first, last, this), ...); } } @@ -807,10 +835,8 @@ public: template void compact() { if constexpr(sizeof...(Component) == 0) { - for(auto pos = pools.size(); pos; --pos) { - if(auto &pdata = pools[pos-1]; pdata.pool) { - pdata.pool->compact(); - } + for(auto &&pdata: pools) { + pdata.pool && (pdata.pool->compact(), true); } } else { (assure()->compact(), ...); @@ -842,8 +868,8 @@ public: void remove_all(const entity_type entity) { ENTT_ASSERT(valid(entity), "Invalid entity"); - for(auto pos = pools.size(); pos; --pos) { - pools[pos-1].pool && pools[pos-1].pool->remove(entity, this); + for(auto &&pdata: pools) { + pdata.pool && pdata.pool->remove(entity, this); } } @@ -989,10 +1015,8 @@ public: template void clear() { if constexpr(sizeof...(Component) == 0) { - for(auto pos = pools.size(); pos; --pos) { - if(auto &pdata = pools[pos-1]; pdata.pool) { - pdata.pool->clear(this); - } + for(auto &&pdata: pools) { + pdata.pool && (pdata.pool->clear(this), true); } each([this](const auto entity) { release_entity(entity, version(entity) + 1u); }); @@ -1216,8 +1240,8 @@ public: */ template [[nodiscard]] basic_runtime_view runtime_view(ItComp first, ItComp last, ItExcl from = {}, ItExcl to = {}) const { - std::vector *> component(std::distance(first, last)); - std::vector *> filter(std::distance(from, to)); + std::vector component(std::distance(first, last)); + std::vector filter(std::distance(from, to)); std::transform(first, last, component.begin(), [this](const auto ctype) { const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.poly && pdata.poly->value_type().hash() == ctype; }); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index e7be97368..fa65a8174 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -539,29 +539,29 @@ TEST(Registry, RangeDestroy) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.valid(e0)); - ASSERT_TRUE(registry.valid(e1)); - ASSERT_TRUE(registry.valid(e2)); + ASSERT_TRUE(registry.valid(entities[0u])); + ASSERT_TRUE(registry.valid(entities[1u])); + ASSERT_TRUE(registry.valid(entities[2u])); registry.destroy(icview.begin(), icview.end()); + registry.destroy(icview.rbegin(), icview.rend()); - ASSERT_FALSE(registry.valid(e0)); - ASSERT_FALSE(registry.valid(e1)); - ASSERT_TRUE(registry.valid(e2)); + ASSERT_FALSE(registry.valid(entities[0u])); + ASSERT_FALSE(registry.valid(entities[1u])); + ASSERT_TRUE(registry.valid(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 0u); @@ -569,43 +569,57 @@ TEST(Registry, RangeDestroy) { registry.destroy(iview.begin(), iview.end()); - ASSERT_FALSE(registry.valid(e2)); - ASSERT_NO_FATAL_FAILURE(registry.destroy(iview.begin(), iview.end())); + ASSERT_FALSE(registry.valid(entities[2u])); + ASSERT_NO_FATAL_FAILURE(registry.destroy(iview.rbegin(), iview.rend())); ASSERT_EQ(iview.size(), 0u); ASSERT_EQ(icview.size_hint(), 0u); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 0u); + + registry.create(std::begin(entities), std::end(entities)); + registry.insert(std::begin(entities), std::end(entities)); + + ASSERT_TRUE(registry.valid(entities[0u])); + ASSERT_TRUE(registry.valid(entities[1u])); + ASSERT_TRUE(registry.valid(entities[2u])); + ASSERT_EQ(registry.size(), 3u); + + registry.destroy(std::begin(entities), std::end(entities)); + + ASSERT_FALSE(registry.valid(entities[0u])); + ASSERT_FALSE(registry.valid(entities[1u])); + ASSERT_FALSE(registry.valid(entities[2u])); + ASSERT_EQ(registry.size(), 0u); } TEST(Registry, StableDestroy) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.valid(e0)); - ASSERT_TRUE(registry.valid(e1)); - ASSERT_TRUE(registry.valid(e2)); + ASSERT_TRUE(registry.valid(entities[0u])); + ASSERT_TRUE(registry.valid(entities[1u])); + ASSERT_TRUE(registry.valid(entities[2u])); registry.destroy(icview.begin(), icview.end()); - ASSERT_FALSE(registry.valid(e0)); - ASSERT_FALSE(registry.valid(e1)); - ASSERT_TRUE(registry.valid(e2)); + ASSERT_FALSE(registry.valid(entities[0u])); + ASSERT_FALSE(registry.valid(entities[1u])); + ASSERT_TRUE(registry.valid(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 2u); @@ -613,7 +627,7 @@ TEST(Registry, StableDestroy) { registry.destroy(iview.begin(), iview.end()); - ASSERT_FALSE(registry.valid(e2)); + ASSERT_FALSE(registry.valid(entities[2u])); ASSERT_EQ(iview.size(), 0u); ASSERT_EQ(icview.size_hint(), 0u); @@ -624,20 +638,20 @@ TEST(Registry, StableDestroy) { TEST(Registry, ReleaseVersion) { entt::registry registry; + entt::entity entities[2u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - ASSERT_EQ(registry.current(e0), entt::registry::version_type{}); - ASSERT_EQ(registry.current(e1), entt::registry::version_type{}); + ASSERT_EQ(registry.current(entities[0u]), entt::registry::version_type{}); + ASSERT_EQ(registry.current(entities[1u]), entt::registry::version_type{}); - registry.release(e0); - registry.release(e1, 3); + registry.release(entities[0u]); + registry.release(entities[1u], 3); - ASSERT_DEATH(registry.release(e0), ""); - ASSERT_DEATH(registry.release(e1, 3), ""); - ASSERT_EQ(registry.current(e0), entt::registry::version_type{1}); - ASSERT_EQ(registry.current(e1), entt::registry::version_type{3}); + ASSERT_DEATH(registry.release(entities[0u]), ""); + ASSERT_DEATH(registry.release(entities[1u], 3), ""); + ASSERT_EQ(registry.current(entities[0u]), entt::registry::version_type{1}); + ASSERT_EQ(registry.current(entities[1u]), entt::registry::version_type{3}); } TEST(Registry, RangeRelease) { @@ -789,17 +803,17 @@ TEST(Registry, View) { auto mview = registry.view(); auto iview = registry.view(); auto cview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - registry.emplace(e0, 0); - registry.emplace(e0, 'c'); + registry.create(std::begin(entities), std::end(entities)); - const auto e1 = registry.create(); - registry.emplace(e1, 0); + registry.emplace(entities[0u], 0); + registry.emplace(entities[0u], 'c'); - const auto e2 = registry.create(); - registry.emplace(e2, 0); - registry.emplace(e2, 'c'); + registry.emplace(entities[1u], 0); + + registry.emplace(entities[2u], 0); + registry.emplace(entities[2u], 'c'); ASSERT_EQ(iview.size(), 3u); ASSERT_EQ(cview.size(), 2u); @@ -1245,6 +1259,7 @@ TEST(Registry, ConstructWithComponents) { TEST(Registry, Signals) { entt::registry registry; + entt::entity entities[2u]; listener listener; registry.on_construct().connect<&listener::incr>(listener); @@ -1252,138 +1267,126 @@ TEST(Registry, Signals) { registry.on_construct().connect<&listener::incr>(listener); registry.on_destroy().connect<&listener::decr>(listener); - auto e0 = registry.create(); - auto e1 = registry.create(); - - registry.emplace(e0); - registry.emplace(e1); + registry.create(std::begin(entities), std::end(entities)); + registry.insert(std::begin(entities), std::end(entities)); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e1); + ASSERT_EQ(listener.last, entities[1u]); - registry.emplace(e1); - registry.emplace(e0); + registry.insert(std::rbegin(entities), std::rend(entities)); ASSERT_EQ(listener.counter, 4); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); - registry.erase(e0); - registry.erase(e0); + registry.erase(entities[0u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); registry.on_destroy().disconnect<&listener::decr>(listener); registry.on_destroy().disconnect<&listener::decr>(listener); - registry.erase(e1); - registry.erase(e1); + registry.erase(entities[1u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); registry.on_construct().disconnect<&listener::incr>(listener); registry.on_construct().disconnect<&listener::incr>(listener); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); registry.on_construct().connect<&listener::incr>(listener); registry.on_destroy().connect<&listener::decr>(listener); - registry.emplace(e0); - registry.erase(e1); + registry.emplace(entities[0u]); + registry.erase(entities[1u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e1); + ASSERT_EQ(listener.last, entities[1u]); registry.on_construct().connect<&listener::incr>(listener); registry.on_destroy().connect<&listener::decr>(listener); - registry.erase(e1); - registry.emplace(e0); + registry.erase(entities[1u]); + registry.emplace(entities[0u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); - registry.clear(); - registry.clear(); + registry.clear(); ASSERT_EQ(listener.counter, 0); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); - registry.emplace(e0); - registry.emplace(e1); - registry.emplace(e0); - registry.emplace(e1); - - registry.destroy(e1); + registry.insert(std::begin(entities), std::end(entities)); + registry.insert(std::begin(entities), std::end(entities)); + registry.destroy(entities[1u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e1); + ASSERT_EQ(listener.last, entities[1u]); - registry.erase(e0); - registry.erase(e0); - registry.emplace_or_replace(e0); - registry.emplace_or_replace(e0); + registry.erase(entities[0u]); + registry.emplace_or_replace(entities[0u]); + registry.emplace_or_replace(entities[0u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); registry.on_destroy().disconnect<&listener::decr>(listener); registry.on_destroy().disconnect<&listener::decr>(listener); - registry.emplace_or_replace(e0); - registry.emplace_or_replace(e0); + registry.emplace_or_replace(entities[0u]); + registry.emplace_or_replace(entities[0u]); ASSERT_EQ(listener.counter, 2); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); registry.on_update().connect<&listener::incr>(listener); registry.on_update().connect<&listener::incr>(listener); - registry.emplace_or_replace(e0); - registry.emplace_or_replace(e0); + registry.emplace_or_replace(entities[0u]); + registry.emplace_or_replace(entities[0u]); ASSERT_EQ(listener.counter, 4); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); - registry.replace(e0); - registry.replace(e0); + registry.replace(entities[0u]); + registry.replace(entities[0u]); ASSERT_EQ(listener.counter, 6); - ASSERT_EQ(listener.last, e0); + ASSERT_EQ(listener.last, entities[0u]); } TEST(Registry, Insert) { entt::registry registry; + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_FALSE(registry.all_of(e0)); - ASSERT_FALSE(registry.all_of(e1)); - ASSERT_FALSE(registry.all_of(e2)); + ASSERT_FALSE(registry.all_of(entities[0u])); + ASSERT_FALSE(registry.all_of(entities[1u])); + ASSERT_FALSE(registry.all_of(entities[2u])); const auto icview = registry.view(); registry.insert(icview.begin(), icview.end(), 3.f); - ASSERT_EQ(registry.get(e0), 3.f); - ASSERT_EQ(registry.get(e1), 3.f); - ASSERT_FALSE(registry.all_of(e2)); + ASSERT_EQ(registry.get(entities[0u]), 3.f); + ASSERT_EQ(registry.get(entities[1u]), 3.f); + ASSERT_FALSE(registry.all_of(entities[2u])); registry.clear(); float value[3]{0.f, 1.f, 2.f}; @@ -1391,40 +1394,39 @@ TEST(Registry, Insert) { const auto iview = registry.view(); registry.insert(iview.data(), iview.data() + iview.size(), value); - ASSERT_EQ(registry.get(e0), 0.f); - ASSERT_EQ(registry.get(e1), 1.f); - ASSERT_EQ(registry.get(e2), 2.f); + ASSERT_EQ(registry.get(entities[0u]), 0.f); + ASSERT_EQ(registry.get(entities[1u]), 1.f); + ASSERT_EQ(registry.get(entities[2u]), 2.f); } TEST(Registry, Erase) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.any_of(e0)); - ASSERT_TRUE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_TRUE(registry.any_of(entities[0u])); + ASSERT_TRUE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); - registry.erase(e0); - registry.erase(icview.begin(), icview.end()); + registry.erase(entities[0u]); registry.erase(icview.begin(), icview.end()); + registry.erase(icview.rbegin(), icview.rend()); - ASSERT_FALSE(registry.any_of(e0)); - ASSERT_FALSE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[0u])); + ASSERT_FALSE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 0u); @@ -1432,46 +1434,61 @@ TEST(Registry, Erase) { registry.erase(iview.begin(), iview.end()); - ASSERT_DEATH(registry.erase(e0), ""); - ASSERT_DEATH(registry.erase(e1), ""); + ASSERT_DEATH(registry.erase(entities[0u]), ""); + ASSERT_DEATH(registry.erase(entities[1u]), ""); - ASSERT_FALSE(registry.any_of(e2)); - ASSERT_NO_FATAL_FAILURE(registry.erase(iview.begin(), iview.end())); + ASSERT_FALSE(registry.any_of(entities[2u])); + ASSERT_NO_FATAL_FAILURE(registry.erase(iview.rbegin(), iview.rend())); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 1u); + + registry.insert(std::begin(entities), std::end(entities)); + registry.insert(std::begin(entities), std::end(entities)); + + ASSERT_EQ(registry.size(), 3u); + ASSERT_EQ(registry.size(), 3u); + + registry.erase(std::begin(entities), std::end(entities)); + + ASSERT_DEATH((registry.erase(std::begin(entities), std::end(entities))), ""); + ASSERT_EQ(registry.size(), 0u); + ASSERT_EQ(registry.size(), 0u); + + ASSERT_FALSE(registry.orphan(entities[0u])); + ASSERT_TRUE(registry.orphan(entities[1u])); + ASSERT_TRUE(registry.orphan(entities[2u])); } TEST(Registry, StableErase) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.any_of(e0)); - ASSERT_TRUE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_TRUE(registry.any_of(entities[0u])); + ASSERT_TRUE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); - registry.erase(e0); + registry.erase(entities[0u]); registry.erase(icview.begin(), icview.end()); registry.erase(icview.begin(), icview.end()); - ASSERT_FALSE(registry.any_of(e0)); - ASSERT_FALSE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[0u])); + ASSERT_FALSE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 2u); @@ -1479,10 +1496,10 @@ TEST(Registry, StableErase) { registry.erase(iview.begin(), iview.end()); - ASSERT_DEATH(registry.erase(e0), ""); - ASSERT_DEATH(registry.erase(e1), ""); + ASSERT_DEATH(registry.erase(entities[0u]), ""); + ASSERT_DEATH(registry.erase(entities[1u]), ""); - ASSERT_FALSE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 2u); @@ -1493,32 +1510,31 @@ TEST(Registry, Remove) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.any_of(e0)); - ASSERT_TRUE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_TRUE(registry.any_of(entities[0u])); + ASSERT_TRUE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); - registry.remove(e0); + registry.remove(entities[0u]); ASSERT_EQ((registry.remove(icview.begin(), icview.end())), 2u); - ASSERT_EQ((registry.remove(icview.begin(), icview.end())), 0u); + ASSERT_EQ((registry.remove(icview.rbegin(), icview.rend())), 0u); - ASSERT_FALSE(registry.any_of(e0)); - ASSERT_FALSE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[0u])); + ASSERT_FALSE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 0u); @@ -1526,47 +1542,62 @@ TEST(Registry, Remove) { ASSERT_EQ((registry.remove(iview.begin(), iview.end())), 1u); - ASSERT_EQ(registry.remove(e0), 0u); - ASSERT_EQ(registry.remove(e1), 0u); + ASSERT_EQ(registry.remove(entities[0u]), 0u); + ASSERT_EQ(registry.remove(entities[1u]), 0u); - ASSERT_FALSE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[2u])); ASSERT_EQ(registry.remove(iview.begin(), iview.end()), 0u); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 1u); + + registry.insert(std::begin(entities), std::end(entities)); + registry.insert(std::begin(entities), std::end(entities)); + + ASSERT_EQ(registry.size(), 3u); + ASSERT_EQ(registry.size(), 3u); + + registry.remove(std::begin(entities), std::end(entities)); + registry.remove(std::begin(entities), std::end(entities)); + + ASSERT_EQ(registry.size(), 0u); + ASSERT_EQ(registry.size(), 0u); + + ASSERT_FALSE(registry.orphan(entities[0u])); + ASSERT_TRUE(registry.orphan(entities[1u])); + ASSERT_TRUE(registry.orphan(entities[2u])); } TEST(Registry, StableRemove) { entt::registry registry; const auto iview = registry.view(); const auto icview = registry.view(); + entt::entity entities[3u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); - const auto e2 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); - registry.emplace(e2); + registry.emplace(entities[2u]); - ASSERT_TRUE(registry.any_of(e0)); - ASSERT_TRUE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_TRUE(registry.any_of(entities[0u])); + ASSERT_TRUE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); - registry.remove(e0); + registry.remove(entities[0u]); ASSERT_EQ((registry.remove(icview.begin(), icview.end())), 2u); - ASSERT_EQ((registry.remove(icview.begin(), icview.end())), 0u); + ASSERT_EQ((registry.remove(icview.rbegin(), icview.rend())), 0u); - ASSERT_FALSE(registry.any_of(e0)); - ASSERT_FALSE(registry.all_of(e1)); - ASSERT_TRUE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[0u])); + ASSERT_FALSE(registry.all_of(entities[1u])); + ASSERT_TRUE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 1u); ASSERT_EQ(registry.size(), 2u); @@ -1574,10 +1605,10 @@ TEST(Registry, StableRemove) { ASSERT_EQ((registry.remove(iview.begin(), iview.end())), 1u); - ASSERT_EQ(registry.remove(e0), 0u); - ASSERT_EQ(registry.remove(e1), 0u); + ASSERT_EQ(registry.remove(entities[0u]), 0u); + ASSERT_EQ(registry.remove(entities[1u]), 0u); - ASSERT_FALSE(registry.any_of(e2)); + ASSERT_FALSE(registry.any_of(entities[2u])); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 2u); @@ -1586,21 +1617,20 @@ TEST(Registry, StableRemove) { TEST(Registry, Compact) { entt::registry registry; + entt::entity entities[2u]; - const auto e0 = registry.create(); - const auto e1 = registry.create(); + registry.create(std::begin(entities), std::end(entities)); - registry.emplace(e0); - registry.emplace(e0); + registry.emplace(entities[0u]); + registry.emplace(entities[0u]); - registry.emplace(e1); - registry.emplace(e1); + registry.emplace(entities[1u]); + registry.emplace(entities[1u]); ASSERT_EQ(registry.size(), 2u); ASSERT_EQ(registry.size(), 2u); - registry.destroy(e0); - registry.destroy(e1); + registry.destroy(std::begin(entities), std::end(entities)); ASSERT_EQ(registry.size(), 0u); ASSERT_EQ(registry.size(), 2u);