Przeglądaj źródła

added exclusion list to registry::clone (close #286)

Michele Caini 6 lat temu
rodzic
commit
e0e51b51b7
2 zmienionych plików z 37 dodań i 3 usunięć
  1. 11 3
      src/entt/entity/registry.hpp
  2. 26 0
      test/entt/entity/registry.cpp

+ 11 - 3
src/entt/entity/registry.hpp

@@ -1447,6 +1447,10 @@ public:
      * If no components are provided, the registry will try to clone all the
      * existing pools.
      *
+     * This feature supports exclusion lists. The excluded types have higher
+     * priority than those indicated for cloning. An excluded type will never be
+     * cloned.
+     *
      * @note
      * There isn't an efficient way to know if all the entities are assigned at
      * least one component once copied. Therefore, there may be orphans. It is
@@ -1465,17 +1469,21 @@ public:
      * be cloned.
      *
      * @tparam Component Types of components to clone.
+     * @tparam Exclude Types of components not to be cloned.
      * @return A fresh copy of the registry.
      */
-    template<typename... Component>
-    basic_registry clone() const {
+    template<typename... Component, typename... Exclude>
+    basic_registry clone(exclude_t<Exclude...> = {}) const {
         static_assert(std::conjunction_v<std::is_copy_constructible<Component>...>);
         basic_registry other;
 
         other.pools.resize(pools.size());
 
         for(auto pos = pools.size(); pos; --pos) {
-            if(auto &pdata = pools[pos-1]; pdata.pool && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))) {
+            if(auto &pdata = pools[pos-1]; pdata.pool
+                    && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type<Component>())))
+                    && !((pdata.runtime_type == to_integer(type<Exclude>())) || ...))
+            {
                 auto &curr = other.pools[pos-1];
                 curr.clone = pdata.clone;
                 curr.remove = pdata.remove;

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

@@ -1377,6 +1377,32 @@ TEST(Registry, Clone) {
     other.reset();
 }
 
+TEST(Registry, CloneExclude) {
+    entt::registry registry;
+    entt::registry other;
+
+    const auto entity = registry.create();
+    registry.assign<int>(entity);
+    registry.assign<char>(entity);
+
+    other = registry.clone<int, char>(entt::exclude<char>);
+
+    ASSERT_TRUE(other.has(entity));
+    ASSERT_TRUE(other.has<int>(entity));
+    ASSERT_FALSE(other.has<char>(entity));
+
+    other = registry.clone(entt::exclude<int>);
+
+    ASSERT_TRUE(other.has(entity));
+    ASSERT_FALSE(other.has<int>(entity));
+    ASSERT_TRUE(other.has<char>(entity));
+
+    other = registry.clone(entt::exclude<int, char>);
+
+    ASSERT_TRUE(other.has(entity));
+    ASSERT_TRUE(other.orphan(entity));
+}
+
 TEST(Registry, CloneMoveOnlyComponent) {
     entt::registry registry;
     const auto entity = registry.create();