registry: ::assign to assign entities to an empty registry

This commit is contained in:
Michele Caini
2020-01-12 00:29:36 +01:00
parent 986cd03732
commit ee5156704d
4 changed files with 49 additions and 3 deletions

7
TODO
View File

@@ -6,7 +6,6 @@
* add opaque input iterators to views and groups that return tuples <entity, T &...> (proxy), multi-pass guaranteed
* allow to replace std:: with custom implementations
* custom (decoupled) pools ==> N-buffering, shared components, multi-model, hibitsets, and so on
* snapshot rework/deprecation
* add examples (and credits) from @alanjfs :)
* static reflection, hint: template<> meta_type_t<Type>: meta_descriptor<name, func..., props..., etc...>
* add meta support to registry (eg entity for each component and opaque get)
@@ -16,7 +15,9 @@
* can we write a bool conv func for entt::entity that silently compares it to null?
* reset... reset everywhere...
* document undocumented parts (entt::overload and a few others)
* range-assign cannot return iterators (eg group or sort-like listeners, see #386)
* any-of rule for views/groups (eg entity has A and any of B/C/D)
- get -> all, exclude -> none
* registry::clear should clear entities etc
* WIP: snapshot rework/deprecation
- range-assign cannot return iterators (eg group or sort-like listeners, see #386)
- remove snapshot/loader from registry, make them external (faster) tools

View File

@@ -5,6 +5,7 @@
#include <cstdint>
#include <type_traits>
#include "../config/config.h"
#include "../core/type_traits.hpp"
namespace entt {

View File

@@ -650,6 +650,32 @@ public:
return assure<Component>().assign(*this, first, last, std::forward<Args>(args)...);
}
/**
* @brief Assigns entities to an empty registry.
*
* @warning
* An assertion will abort the execution at runtime in debug mode if all
* pools aren't empty. Groups and context variables are ignored.
*
* @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<typename It>
void assign(It first, It last) {
ENTT_ASSERT(std::all_of(pools.cbegin(), pools.cend(), [](auto &&cpool) { return cpool.pool->empty(); }));
entities.assign(first, last);
destroyed = null;
for(std::size_t pos{}, end = entities.size(); pos < end; ++pos) {
if((to_integral(entities[pos]) & traits_type::entity_mask) != pos) {
const auto version = to_integral(entities[pos]) & (traits_type::version_mask << traits_type::entity_shift);
entities[pos] = entity_type{to_integral(destroyed) | version};
destroyed = entity_type(pos);
}
}
}
/**
* @brief Assigns or replaces the given component for an entity.
*

View File

@@ -1593,3 +1593,21 @@ TEST(Registry, StableAssign) {
ASSERT_EQ(registry.assign<int>(registry.create(), 1), 1);
}
TEST(Registry, AssignEntities) {
entt::registry registry;
entt::entity entities[3];
registry.create(std::begin(entities), std::end(entities));
registry.destroy(entities[1]);
registry.destroy(entities[2]);
entt::registry other;
other.assign(registry.data(), registry.data() + registry.size());
ASSERT_EQ(registry.size(), other.size());
ASSERT_TRUE(other.valid(entities[0]));
ASSERT_FALSE(other.valid(entities[1]));
ASSERT_FALSE(other.valid(entities[2]));
ASSERT_EQ(registry.create(), other.create());
ASSERT_EQ(other.entity(other.create()), entities[1]);
}