diff --git a/TODO b/TODO index b7ca01024..d5809d352 100644 --- a/TODO +++ b/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 diff --git a/src/entt/entity/mixin.hpp b/src/entt/entity/mixin.hpp index 2dab36c63..df904c6ed 100644 --- a/src/entt/entity/mixin.hpp +++ b/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(*this)) { + destruction.publish(*owner, entt); + } + } else { + for(const auto entt: static_cast(*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); diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index b61444507..7995aefc9 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/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); } /** diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 41889b9f5..c2f0f7f23 100644 --- a/src/entt/entity/storage.hpp +++ b/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(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.