registry: added ::remove_all to orphan entities (close #446)

This commit is contained in:
Michele Caini
2020-04-07 23:48:07 +02:00
parent a7faab53b9
commit ed7382995c
2 changed files with 36 additions and 27 deletions

View File

@@ -548,13 +548,12 @@ public:
* @brief Assigns entities to an empty registry.
*
* This function is intended for use in conjunction with `raw`.<br/>
* Don't try to inject ranges of randomly generated entities because there
* is no guarantee that the registry will continue to function properly in
* this case.
* Don't try to inject ranges of randomly generated entities. There is no
* guarantee that a registry will continue to work properly in this case.
*
* @warning
* An assertion will abort the execution at runtime in debug mode if all
* pools aren't empty. Groups and context variables are ignored.
* pools aren't empty.
*
* @tparam It Type of input iterator.
* @param first An iterator to the first element of the range of entities.
@@ -581,32 +580,12 @@ public:
* When an entity is destroyed, its version is updated and the identifier
* can be recycled at any time.
*
* @warning
* In case there are listeners that observe the destruction of components
* and assign other components to the entity in their bodies, the result of
* invoking this function may not be as expected. In the worst case, it
* could lead to undefined behavior. An assertion will abort the execution
* at runtime in debug mode if a violation is detected.
*
* @warning
* Attempting to use an invalid entity results in undefined behavior.<br/>
* An assertion will abort the execution at runtime in debug mode in case of
* invalid entity.
* @sa remove_all
*
* @param entity A valid entity identifier.
*/
void destroy(const entity_type entity) {
ENTT_ASSERT(valid(entity));
for(auto pos = pools.size(); pos; --pos) {
if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) {
pdata.remove(*pdata.pool, *this, entity);
}
}
// just a way to protect users from listeners that attach components
ENTT_ASSERT(orphan(entity));
remove_all(entity);
// lengthens the implicit list of destroyed entities
const auto entt = to_integral(entity) & traits_type::entity_mask;
const auto version = ((to_integral(entity) >> traits_type::entity_shift) + 1) << traits_type::entity_shift;
@@ -885,6 +864,36 @@ public:
}(assure<Component>()), ...);
}
/**
* @brief Removes all the components from an entity and makes it orphaned.
*
* @warning
* In case there are listeners that observe the destruction of components
* and assign other components to the entity in their bodies, the result of
* invoking this function may not be as expected. In the worst case, it
* could lead to undefined behavior. An assertion will abort the execution
* at runtime in debug mode if a violation is detected.
*
* @warning
* Attempting to use an invalid entity results in undefined behavior.<br/>
* An assertion will abort the execution at runtime in debug mode in case of
* invalid entity.
*
* @param entity A valid entity identifier.
*/
void remove_all(const entity_type entity) {
ENTT_ASSERT(valid(entity));
for(auto pos = pools.size(); pos; --pos) {
if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) {
pdata.remove(*pdata.pool, *this, entity);
}
}
// just a way to protect users from listeners that attach components
ENTT_ASSERT(orphan(entity));
}
/**
* @brief Checks if an entity has all the given components.
*

View File

@@ -527,7 +527,7 @@ TEST(Registry, Orphans) {
ASSERT_EQ(tot, 1u);
tot = {};
registry.each([&](auto entity) { registry.remove_if_exists<int>(entity); });
registry.each([&](auto entity) { registry.remove_all(entity); });
registry.orphans([&](auto) { ++tot; });
ASSERT_EQ(tot, 3u);
registry.clear();