diff --git a/TODO b/TODO index 9db2bccb0..0ce9647cd 100644 --- a/TODO +++ b/TODO @@ -31,7 +31,6 @@ - entity for each component - opaque get - and so on (I'm lazy) :) +* registry::each to iterate all components of an entity * named types: almost-stable index optimization for direct access to pools, no more linear searches - can implicitly generate types for meta benefit from a similar approach? - * registry::each to iterate all components of an entity -* multi component registry::remove and some others? diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 32fda0636..e7d7bf82c 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -1,4 +1,4 @@ -#ifndef ENTT_ENTITY_REGISTRY_HPP +#ifndef ENTT_ENTITY_REGISTRY_HPP #define ENTT_ENTITY_REGISTRY_HPP @@ -640,8 +640,8 @@ public: * @sa destroy * * @tparam It Type of input iterator. - * @param first An iterator to the first element of the range to destroy. - * @param last An iterator past the last element of the range to destroy. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. */ template void destroy(It first, It last) { @@ -683,8 +683,8 @@ public: * @tparam Component Type of component to create. * @tparam It Type of input iterator. * @tparam Args Types of arguments to use to construct the component. - * @param first An iterator to the first element of the range to assign. - * @param last An iterator past the last element of the range to assign. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. * @param args Parameters to use to initialize the component. * @return An iterator to the list of components just created. */ @@ -714,6 +714,23 @@ public: (assure()->remove(*this, entity), ...); } + /** + * @brief Removes the given components from all the entities in a range. + * + * @see remove + * + * @tparam Component Types of components to remove. + * @tparam It Type of input iterator. + * @param first An iterator to the first element of the range of entities. + * @param last An iterator past the last element of the range of entities. + */ + template + void remove(It first, It last) { + ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); + // useless this-> used to suppress a warning with clang + std::for_each(first, last, [this](const auto entity) { this->remove(entity); }); + } + /** * @brief Checks if an entity has all the given components. * diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index d70408de5..ceb1b1a30 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1099,6 +1099,34 @@ TEST(Registry, RangeAssign) { ASSERT_EQ(registry.get(*(++view.begin())), 1.f); } +TEST(Registry, RangeRemove) { + entt::registry registry; + + const auto e0 = registry.create(); + const auto e1 = registry.create(); + const auto e2 = registry.create(); + + registry.assign(e0); + registry.assign(e0); + registry.assign(e0); + + registry.assign(e1); + registry.assign(e1); + + registry.assign(e2); + + ASSERT_TRUE(registry.has(e0)); + ASSERT_TRUE(registry.has(e1)); + ASSERT_TRUE(registry.has(e2)); + + const auto view = registry.view(); + registry.remove(view.begin(), view.end()); + + ASSERT_FALSE(registry.has(e0)); + ASSERT_FALSE(registry.has(e1)); + ASSERT_TRUE(registry.has(e2)); +} + TEST(Registry, CreateManyEntitiesAtOnce) { entt::registry registry; entt::entity entities[3];