revert: too risky a function
This commit is contained in:
35
README.md
35
README.md
@@ -851,16 +851,12 @@ whether all the components have to be accessed or not.
|
||||
function template of a registry during iterations, if possible. However, keep in
|
||||
mind that it works only with the components of the view itself.
|
||||
|
||||
### Give me everything, whatever it means
|
||||
### Give me everything
|
||||
|
||||
Views are narrow windows on the entire list of entities. They work by filtering
|
||||
entities according to their components.<br/>
|
||||
In some cases there may be the need to iterate all the entities regardless of
|
||||
their components. The registry offers a couple of member functions to do that:
|
||||
`each` and `alive`.
|
||||
|
||||
The former returns all the entities ever created, no matter if they are still in
|
||||
use or not:
|
||||
their components. The registry offers a specific member function to do that:
|
||||
|
||||
```cpp
|
||||
registry.each([](auto entity) {
|
||||
@@ -868,34 +864,15 @@ registry.each([](auto entity) {
|
||||
});
|
||||
```
|
||||
|
||||
The latter returns an entity only if it's still in use (in other words, the
|
||||
entity is returned only if it hasn't been destroyed):
|
||||
|
||||
```cpp
|
||||
registry.alive([](auto entity) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
Each entity ever created is returned, no matter if it's in use or not.<br/>
|
||||
Usually, filtering entities that aren't currently in use is more expensive than
|
||||
iterating them all and filtering out those in which one isn't interested.
|
||||
|
||||
As a rule of thumb, consider using a view if the goal is to iterate entities
|
||||
that have a determinate set of components. A view is usually faster than
|
||||
combining these functions with a bunch of custom tests.<br/>
|
||||
combining this function with a bunch of custom tests.<br/>
|
||||
In all the other cases, this is the way to go.
|
||||
|
||||
There exists also another function to use to retrieve orphans. An orphan is an
|
||||
entity that is still in use and has no assigned components.<br/>
|
||||
The signature of the function is the same of `each` and `alive`:
|
||||
|
||||
```cpp
|
||||
registry.orphans([](auto entity) {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
In general, `each` is pretty fast to run while `alive` is a bit slower because
|
||||
of the check it must perform on each and every entity. For similar reasons,
|
||||
`orphans` can be very slow and should not be used frequently.
|
||||
|
||||
## Side notes
|
||||
|
||||
* Entity identifiers are numbers and nothing more. They are not classes and they
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
#include <type_traits>
|
||||
#include "../core/family.hpp"
|
||||
@@ -402,7 +401,7 @@ public:
|
||||
* function can be used to know if they are still valid or the entity has
|
||||
* been destroyed and potentially recycled.
|
||||
*
|
||||
* The returned entity has no assigned components.
|
||||
* The returned entity has no components assigned.
|
||||
*
|
||||
* @return A valid entity identifier.
|
||||
*/
|
||||
@@ -923,7 +922,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate all the entities ever created.
|
||||
* @brief Iterate entities and applies them the given function object.
|
||||
*
|
||||
* The function object is invoked for each entity, no matter if it's in use
|
||||
* or not.<br/>
|
||||
@@ -942,74 +941,11 @@ public:
|
||||
*/
|
||||
template<typename Func>
|
||||
void each(Func func) const {
|
||||
for(size_type pos{}, last = entities.size(); pos < last; ++pos) {
|
||||
func(entities[pos]);
|
||||
for(auto pos = entities.size(); pos > size_type{0}; --pos) {
|
||||
func(entities[pos-1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate all the entities still in use.
|
||||
*
|
||||
* The function object is invoked for each entity that is still in use.<br/>
|
||||
* The signature of the function should be equivalent to the following:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* void(entity_type);
|
||||
* @endcode
|
||||
*
|
||||
* This function is fairly slow and should not be used frequently.<br/>
|
||||
* Consider using a view if the goal is to iterate entities that have a
|
||||
* determinate set of components. A view is usually faster than combining
|
||||
* this function with a bunch of custom tests.
|
||||
*
|
||||
* @tparam Func Type of the function object to invoke.
|
||||
* @param func A valid function object.
|
||||
*/
|
||||
template<typename Func>
|
||||
void alive(Func func) {
|
||||
std::sort(available.begin(), available.end());
|
||||
|
||||
const auto end= available.cend();
|
||||
auto it = available.cbegin();
|
||||
|
||||
each([func = std::move(func), it, end](auto entity) mutable {
|
||||
if(it != end && *it == entity) {
|
||||
++it;
|
||||
} else {
|
||||
func(entity);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterate orphans and applies them the given function object.
|
||||
*
|
||||
* The function object is invoked for each entity that is still in use and
|
||||
* has no assigned components.<br/>
|
||||
* The signature of the function should be equivalent to the following:
|
||||
*
|
||||
* @code{.cpp}
|
||||
* void(entity_type);
|
||||
* @endcode
|
||||
*
|
||||
* This function can be very slow and should not be used frequently.
|
||||
*
|
||||
* @tparam Func Type of the function object to invoke.
|
||||
* @param func A valid function object.
|
||||
*/
|
||||
template<typename Func>
|
||||
void orphans(Func func) {
|
||||
alive([func = std::move(func), this](auto entity) {
|
||||
for(const auto &pool: pools) {
|
||||
if(pool && pool->has(entity)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
func(entity);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns a standard view for the given components.
|
||||
*
|
||||
|
||||
@@ -174,91 +174,6 @@ TEST(DefaultRegistry, Each) {
|
||||
ASSERT_EQ(match, 0u);
|
||||
}
|
||||
|
||||
TEST(DefaultRegistry, Alive) {
|
||||
entt::DefaultRegistry registry;
|
||||
entt::DefaultRegistry::size_type tot;
|
||||
entt::DefaultRegistry::size_type match;
|
||||
|
||||
registry.create<int>();
|
||||
registry.create<int>();
|
||||
|
||||
tot = 0u;
|
||||
match = 0u;
|
||||
|
||||
registry.alive([&](auto entity) {
|
||||
if(registry.has<int>(entity)) { ++match; }
|
||||
registry.create();
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 2u);
|
||||
ASSERT_EQ(match, 2u);
|
||||
|
||||
tot = 0u;
|
||||
match = 0u;
|
||||
|
||||
registry.alive([&](auto entity) {
|
||||
if(registry.has<int>(entity)) {
|
||||
registry.destroy(entity);
|
||||
++match;
|
||||
}
|
||||
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 4u);
|
||||
ASSERT_EQ(match, 2u);
|
||||
|
||||
tot = 0u;
|
||||
match = 0u;
|
||||
|
||||
registry.alive([&](auto entity) {
|
||||
if(registry.has<int>(entity)) { ++match; }
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 2u);
|
||||
ASSERT_EQ(match, 0u);
|
||||
}
|
||||
|
||||
TEST(DefaultRegistry, Orphans) {
|
||||
entt::DefaultRegistry registry;
|
||||
entt::DefaultRegistry::size_type tot;
|
||||
|
||||
registry.create<int>();
|
||||
registry.create();
|
||||
registry.create<int>();
|
||||
registry.create();
|
||||
|
||||
tot = 0u;
|
||||
|
||||
registry.orphans([&](auto) {
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 2u);
|
||||
|
||||
registry.each([&](auto entity) {
|
||||
registry.reset<int>(entity);
|
||||
});
|
||||
|
||||
tot = 0u;
|
||||
|
||||
registry.orphans([&](auto) {
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 4u);
|
||||
|
||||
registry.reset();
|
||||
tot = 0u;
|
||||
|
||||
registry.orphans([&](auto) {
|
||||
++tot;
|
||||
});
|
||||
|
||||
ASSERT_EQ(tot, 0u);
|
||||
}
|
||||
|
||||
TEST(DefaultRegistry, Types) {
|
||||
entt::DefaultRegistry registry;
|
||||
|
||||
Reference in New Issue
Block a user