registry: destroy with suggested version

This commit is contained in:
Michele Caini
2020-05-05 00:20:51 +02:00
parent 3fc116ab53
commit bdfeb1ae22
3 changed files with 42 additions and 17 deletions

View File

@@ -176,7 +176,8 @@ registry.destroy(view.begin(), view.end());
When an entity is destroyed, the registry can freely reuse it internally with a
slightly different identifier. In particular, the version of an entity is
increased after destruction.<br/>
increased after destruction (unless the overload that forces a version is used
instead of the default one).<br/>
Users can probe an identifier to know the information it carries:
```cpp

View File

@@ -575,7 +575,7 @@ public:
}
/**
* @brief Destroys an entity and lets the registry recycle the identifier.
* @brief Destroys an entity.
*
* When an entity is destroyed, its version is updated and the identifier
* can be recycled at any time.
@@ -585,11 +585,25 @@ public:
* @param entity A valid entity identifier.
*/
void destroy(const entity_type entity) {
destroy(entity, (to_integral(entity) >> traits_type::entity_shift) + 1);
}
/**
* @brief Destroys an entity.
*
* If the entity isn't already destroyed, the suggested version is used
* instead of the implicitly generated one.
*
* @sa remove_all
*
* @param entity A valid entity identifier.
* @param version A desired version upon destruction.
*/
void destroy(const entity_type entity, const version_type version) {
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;
entities[entt] = entity_type{to_integral(destroyed) | version};
entities[entt] = entity_type{to_integral(destroyed) | (version << traits_type::entity_shift)};
destroyed = entity_type{entt};
}

View File

@@ -380,24 +380,40 @@ TEST(Registry, CreateWithHint) {
registry.destroy(e2);
ASSERT_EQ(registry.version(e2), 0);
ASSERT_EQ(registry.current(e2), 1);
ASSERT_EQ(registry.version(e2), entt::registry::version_type{});
ASSERT_EQ(registry.current(e2), entt::registry::version_type{1});
e2 = registry.create();
auto e1 = registry.create(entt::entity{2});
ASSERT_EQ(registry.entity(e2), entt::entity{2});
ASSERT_EQ(registry.version(e2), 1);
ASSERT_EQ(registry.version(e2), entt::registry::version_type{1});
ASSERT_EQ(registry.entity(e1), entt::entity{1});
ASSERT_EQ(registry.version(e1), 0);
ASSERT_EQ(registry.version(e1), entt::registry::version_type{});
registry.destroy(e1);
registry.destroy(e2);
auto e0 = registry.create(entt::entity{0});
ASSERT_EQ(e0, entt::entity{0});
ASSERT_EQ(registry.version(e0), 0);
ASSERT_EQ(registry.version(e0), entt::registry::version_type{});
}
TEST(Registry, DestroyWithVersion) {
entt::registry registry;
const auto e0 = registry.create();
const auto e1 = registry.create();
ASSERT_EQ(registry.current(e0), entt::registry::version_type{});
ASSERT_EQ(registry.current(e1), entt::registry::version_type{});
registry.destroy(e0);
registry.destroy(e1, 3);
ASSERT_EQ(registry.current(e0), entt::registry::version_type{1});
ASSERT_EQ(registry.current(e1), entt::registry::version_type{3});
}
TEST(Registry, CreateDestroyEntities) {
@@ -448,16 +464,10 @@ TEST(Registry, CreateDestroyCornerCase) {
TEST(Registry, VersionOverflow) {
entt::registry registry;
const auto entity = registry.create();
registry.destroy(entity);
ASSERT_EQ(registry.version(entity), entt::registry::version_type{});
for(auto i = entt::entt_traits<std::underlying_type_t<entt::entity>>::version_mask; i; --i) {
ASSERT_NE(registry.current(entity), registry.version(entity));
registry.destroy(registry.create());
}
registry.destroy(entity, entt::entt_traits<std::underlying_type_t<entt::entity>>::version_mask);
registry.destroy(registry.create());
ASSERT_EQ(registry.current(entity), registry.version(entity));
}