Преглед изворни кода

registry: destroy with suggested version

Michele Caini пре 5 година
родитељ
комит
bdfeb1ae22
3 измењених фајлова са 42 додато и 17 уклоњено
  1. 2 1
      docs/md/entity.md
  2. 17 3
      src/entt/entity/registry.hpp
  3. 23 13
      test/entt/entity/registry.cpp

+ 2 - 1
docs/md/entity.md

@@ -176,7 +176,8 @@ registry.destroy(view.begin(), view.end());
 
 
 When an entity is destroyed, the registry can freely reuse it internally with a
 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
 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:
 Users can probe an identifier to know the information it carries:
 
 
 ```cpp
 ```cpp

+ 17 - 3
src/entt/entity/registry.hpp

@@ -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
      * When an entity is destroyed, its version is updated and the identifier
      * can be recycled at any time.
      * can be recycled at any time.
@@ -585,11 +585,25 @@ public:
      * @param entity A valid entity identifier.
      * @param entity A valid entity identifier.
      */
      */
     void destroy(const entity_type entity) {
     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);
         remove_all(entity);
         // lengthens the implicit list of destroyed entities
         // lengthens the implicit list of destroyed entities
         const auto entt = to_integral(entity) & traits_type::entity_mask;
         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};
         destroyed = entity_type{entt};
     }
     }
 
 

+ 23 - 13
test/entt/entity/registry.cpp

@@ -380,24 +380,40 @@ TEST(Registry, CreateWithHint) {
 
 
     registry.destroy(e2);
     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();
     e2 = registry.create();
     auto e1 = registry.create(entt::entity{2});
     auto e1 = registry.create(entt::entity{2});
 
 
     ASSERT_EQ(registry.entity(e2), 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.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(e1);
     registry.destroy(e2);
     registry.destroy(e2);
     auto e0 = registry.create(entt::entity{0});
     auto e0 = registry.create(entt::entity{0});
 
 
     ASSERT_EQ(e0, 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) {
 TEST(Registry, CreateDestroyEntities) {
@@ -448,16 +464,10 @@ TEST(Registry, CreateDestroyCornerCase) {
 
 
 TEST(Registry, VersionOverflow) {
 TEST(Registry, VersionOverflow) {
     entt::registry registry;
     entt::registry registry;
-
     const auto entity = registry.create();
     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));
     ASSERT_EQ(registry.current(entity), registry.version(entity));
 }
 }