registry: make ::remove and ::erase work also with iterators returned by views

This commit is contained in:
Michele Caini
2021-05-07 11:16:32 +02:00
parent c6bba98828
commit c4b169edd1
3 changed files with 84 additions and 17 deletions

2
TODO
View File

@@ -7,6 +7,7 @@
* custom pools example (multi instance, tables, enable/disable, and so on...)
WIP:
* isolate view iterator, unwrap iterators in registry ::remove/::erase/::destroy to use the faster solution for non-view iterators
* compressed pair to exploit ebo in sparse set and the others
* rename sparse_set::entity_type (and the others) to value_type
* scheduler, use any (or poly?) instead of unique_ptr
@@ -28,5 +29,4 @@ WIP:
* deprecate non-owning groups in favor of owning views and view packs, introduce lazy owning views
* pagination doesn't work nicely across boundaries probably, give it a look. RO operations are fine, adding components maybe not.
* snapshot: support for range-based archives
* page size 0 -> page less mode
* add example: 64 bit ids with 32 bits reserved for users' purposes

View File

@@ -696,9 +696,13 @@ public:
*/
template<typename... Component, typename It>
size_type remove(It first, It last) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
static_assert(sizeof...(Component) > 0, "Provide one or more component types");
return (assure<Component>()->remove(first, last, this) + ... + size_type{});
size_type count{};
for(; first != last; ++first) {
count += remove<Component...>(*first);
}
return count;
}
/**
@@ -730,9 +734,9 @@ public:
*/
template<typename... Component, typename It>
void erase(It first, It last) {
ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); }), "Invalid entity");
static_assert(sizeof...(Component) > 0, "Provide one or more component types");
(assure<Component>()->erase(first, last, this), ...);
for(; first != last; ++first) {
erase<Component...>(*first);
}
}
/*! @copydoc remove */

View File

@@ -1194,6 +1194,8 @@ TEST(Registry, Signals) {
TEST(Registry, RangeDestroy) {
entt::registry registry;
const auto iview = registry.view<int>();
const auto icview = registry.view<int, char>();
const auto e0 = registry.create();
const auto e1 = registry.create();
@@ -1212,23 +1214,16 @@ TEST(Registry, RangeDestroy) {
ASSERT_TRUE(registry.valid(e1));
ASSERT_TRUE(registry.valid(e2));
{
const auto view = registry.view<int, char>();
registry.destroy(view.begin(), view.end());
}
registry.destroy(icview.begin(), icview.end());
ASSERT_FALSE(registry.valid(e0));
ASSERT_FALSE(registry.valid(e1));
ASSERT_TRUE(registry.valid(e2));
{
const auto view = registry.view<int>();
registry.destroy(view.begin(), view.end());
}
registry.destroy(iview.begin(), iview.end());
ASSERT_FALSE(registry.valid(e0));
ASSERT_FALSE(registry.valid(e1));
ASSERT_FALSE(registry.valid(e2));
ASSERT_NO_FATAL_FAILURE(registry.destroy(iview.begin(), iview.end()));
}
TEST(Registry, Insert) {
@@ -1303,6 +1298,40 @@ TEST(Registry, Erase) {
ASSERT_TRUE(registry.all_of<int>(e2));
}
TEST(Registry, RangeErase) {
entt::registry registry;
const auto iview = registry.view<int>();
const auto icview = registry.view<int, char>();
const auto e0 = registry.create();
const auto e1 = registry.create();
const auto e2 = registry.create();
registry.emplace<int>(e0);
registry.emplace<char>(e0);
registry.emplace<double>(e0);
registry.emplace<int>(e1);
registry.emplace<char>(e1);
registry.emplace<int>(e2);
ASSERT_TRUE(registry.any_of<int>(e0));
ASSERT_TRUE(registry.any_of<int>(e1));
ASSERT_TRUE(registry.any_of<int>(e2));
registry.erase<int, char>(icview.begin(), icview.end());
ASSERT_FALSE(registry.any_of<int>(e0));
ASSERT_FALSE(registry.any_of<int>(e1));
ASSERT_TRUE(registry.any_of<int>(e2));
registry.erase<int>(iview.begin(), iview.end());
ASSERT_FALSE(registry.any_of<int>(e2));
ASSERT_NO_FATAL_FAILURE(registry.erase<int>(iview.begin(), iview.end()));
}
TEST(Registry, Remove) {
entt::registry registry;
@@ -1335,6 +1364,40 @@ TEST(Registry, Remove) {
ASSERT_TRUE(registry.all_of<int>(e2));
}
TEST(Registry, RangeRemove) {
entt::registry registry;
const auto iview = registry.view<int>();
const auto icview = registry.view<int, char>();
const auto e0 = registry.create();
const auto e1 = registry.create();
const auto e2 = registry.create();
registry.emplace<int>(e0);
registry.emplace<char>(e0);
registry.emplace<double>(e0);
registry.emplace<int>(e1);
registry.emplace<char>(e1);
registry.emplace<int>(e2);
ASSERT_TRUE(registry.any_of<int>(e0));
ASSERT_TRUE(registry.any_of<int>(e1));
ASSERT_TRUE(registry.any_of<int>(e2));
registry.remove<int, char>(icview.begin(), icview.end());
ASSERT_FALSE(registry.any_of<int>(e0));
ASSERT_FALSE(registry.any_of<int>(e1));
ASSERT_TRUE(registry.any_of<int>(e2));
registry.remove<int>(iview.begin(), iview.end());
ASSERT_FALSE(registry.any_of<int>(e2));
ASSERT_EQ(registry.remove<int>(iview.begin(), iview.end()), 0u);
}
TEST(Registry, NonOwningGroupInterleaved) {
entt::registry registry;
typename entt::entity entity = entt::null;