Просмотр исходного кода

sparse_set: internal clear_all function

Michele Caini 3 лет назад
Родитель
Сommit
232ffebc1e
4 измененных файлов с 48 добавлено и 14 удалено
  1. 1 1
      TODO
  2. 20 0
      src/entt/entity/mixin.hpp
  3. 8 13
      src/entt/entity/sparse_set.hpp
  4. 19 0
      src/entt/entity/storage.hpp

+ 1 - 1
TODO

@@ -14,7 +14,7 @@ DOC:
 TODO (high prio):
 * check natvis files (periodically :)
 * remove the static storage from the const assure in the registry
-* use sparse set iterator ::data to optimize range functionalities in the registry (exploit the zero-check model)
+* use sparse set iterator ::data to optimize range functionalities in the mixins and the registry (exploit the zero-check model)
 
 WIP:
 * get rid of observers, storage based views made them pointless - document alternatives

+ 20 - 0
src/entt/entity/mixin.hpp

@@ -43,6 +43,26 @@ class sigh_mixin final: public Type {
         }
     }
 
+    void clear_all() final {
+        if(!destruction.empty()) {
+            ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
+
+            if(Type::policy() == deletion_policy::swap_and_pop) {
+                for(const auto entt: static_cast<typename Type::base_type &>(*this)) {
+                    destruction.publish(*owner, entt);
+                }
+            } else {
+                for(const auto entt: static_cast<typename Type::base_type &>(*this)) {
+                    if(entt != tombstone) {
+                        destruction.publish(*owner, entt);
+                    }
+                }
+            }
+        }
+
+        Type::clear_all();
+    }
+
     underlying_iterator try_emplace(const typename Type::entity_type entt, const bool force_back, const void *value) final {
         const auto it = Type::try_emplace(entt, force_back, value);
 

+ 8 - 13
src/entt/entity/sparse_set.hpp

@@ -300,6 +300,13 @@ protected:
         }
     }
 
+    /*! @brief Erases all entities of a sparse set. */
+    virtual void clear_all() {
+        sparse.clear();
+        packed.clear();
+        free_list = tombstone;
+    }
+
     /**
      * @brief Assigns an entity to a sparse set.
      * @param entt A valid identifier.
@@ -968,19 +975,7 @@ public:
 
     /*! @brief Clears a sparse set. */
     void clear() {
-        if(const auto last = end(); free_list == null) {
-            pop(begin(), last);
-        } else {
-            for(auto &&entity: *this) {
-                // tombstone filter on itself
-                if(const auto it = find(entity); it != last) {
-                    pop(it, it + 1u);
-                }
-            }
-        }
-
-        // swap-only sets support
-        compact();
+        empty() || (clear_all(), true);
     }
 
     /**

+ 19 - 0
src/entt/entity/storage.hpp

@@ -349,6 +349,25 @@ protected:
         }
     }
 
+    /*! @brief Erases all entities of a storage. */
+    void clear_all() override {
+        for(auto first = base_type::begin(); first.index() > 0; ++first) {
+            const auto idx = static_cast<size_type>(first.index());
+
+            if constexpr(traits_type::in_place_delete) {
+                if(*first != tombstone) {
+                    base_type::in_place_pop(first);
+                    std::destroy_at(std::addressof(element_at(idx)));
+                }
+            } else {
+                base_type::swap_and_pop(first);
+                std::destroy_at(std::addressof(element_at(idx)));
+            }
+        }
+
+        base_type::clear_all();
+    }
+
     /**
      * @brief Assigns an entity to a storage.
      * @param entt A valid identifier.