Преглед на файлове

registry: erase_if (close #977)

Michele Caini преди 2 години
родител
ревизия
57ec3c85cb
променени са 2 файла, в които са добавени 57 реда и са изтрити 0 реда
  1. 24 0
      src/entt/entity/registry.hpp
  2. 33 0
      test/entt/entity/registry.cpp

+ 24 - 0
src/entt/entity/registry.hpp

@@ -916,6 +916,30 @@ public:
         }
     }
 
+    /**
+     * @brief Erases components satisfying specific criteria from an entity.
+     *
+     * The function type is equivalent to:
+     *
+     * @code{.cpp}
+     * void(const id_type, typename basic_registry<Entity>::base_type &);
+     * @endcode
+     *
+     * Only storages where the entity exists are passed to the function.
+     *
+     * @tparam Func Type of the function object to invoke.
+     * @param entt A valid identifier.
+     * @param func A valid function object.
+     */
+    template<typename Func>
+    void erase_if(const entity_type entt, Func func) {
+        for(auto [id, cpool]: storage()) {
+            if(cpool.contains(entt) && func(id, std::as_const(cpool))) {
+                cpool.erase(entt);
+            }
+        }
+    }
+
     /**
      * @brief Removes all tombstones from a registry or only the pools for the
      * given components.

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

@@ -1735,6 +1735,39 @@ TEST(Registry, StableErase) {
     ASSERT_EQ(registry.storage<double>().size(), 1u);
 }
 
+TEST(Registry, EraseIf) {
+    using namespace entt::literals;
+
+    entt::registry registry;
+    const auto entity = registry.create();
+
+    registry.emplace<int>(entity);
+    registry.storage<int>("other"_hs).emplace(entity);
+    registry.emplace<char>(entity);
+
+    ASSERT_TRUE(registry.storage<int>().contains(entity));
+    ASSERT_TRUE(registry.storage<int>("other"_hs).contains(entity));
+    ASSERT_TRUE(registry.storage<char>().contains(entity));
+
+    registry.erase_if(entity, [](auto &&...) { return false; });
+
+    ASSERT_TRUE(registry.storage<int>().contains(entity));
+    ASSERT_TRUE(registry.storage<int>("other"_hs).contains(entity));
+    ASSERT_TRUE(registry.storage<char>().contains(entity));
+
+    registry.erase_if(entity, [](entt::id_type id, auto &&...) { return id == "other"_hs; });
+
+    ASSERT_TRUE(registry.storage<int>().contains(entity));
+    ASSERT_FALSE(registry.storage<int>("other"_hs).contains(entity));
+    ASSERT_TRUE(registry.storage<char>().contains(entity));
+
+    registry.erase_if(entity, [](auto, const auto &storage) { return storage.type() == entt::type_id<char>(); });
+
+    ASSERT_TRUE(registry.storage<int>().contains(entity));
+    ASSERT_FALSE(registry.storage<int>("other"_hs).contains(entity));
+    ASSERT_FALSE(registry.storage<char>().contains(entity));
+}
+
 TEST(Registry, Remove) {
     entt::registry registry;
     const auto iview = registry.view<int>();