Переглянути джерело

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

Michele Caini 4 роки тому
батько
коміт
c4b169edd1
3 змінених файлів з 84 додано та 17 видалено
  1. 1 1
      TODO
  2. 10 6
      src/entt/entity/registry.hpp
  3. 73 10
      test/entt/entity/registry.cpp

+ 1 - 1
TODO

@@ -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

+ 10 - 6
src/entt/entity/registry.hpp

@@ -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 */

+ 73 - 10
test/entt/entity/registry.cpp

@@ -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;