Przeglądaj źródła

entity: zero sized version support

Michele Caini 2 lat temu
rodzic
commit
1893a8c78d
2 zmienionych plików z 43 dodań i 7 usunięć
  1. 21 4
      src/entt/entity/entity.hpp
  2. 22 3
      test/entt/entity/entity.cpp

+ 21 - 4
src/entt/entity/entity.hpp

@@ -106,7 +106,11 @@ public:
      * @return The integral representation of the version part.
      */
     [[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept {
-        return (static_cast<version_type>(to_integral(value) >> length) & version_mask);
+        if constexpr(Traits::version_mask) {
+            return (static_cast<version_type>(to_integral(value) >> length) & version_mask);
+        } else {
+            return version_type{};
+        }
     }
 
     /**
@@ -130,7 +134,11 @@ public:
      * @return A properly constructed identifier.
      */
     [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept {
-        return value_type{(entity & entity_mask) | (static_cast<entity_type>(version & version_mask) << length)};
+        if constexpr(Traits::version_mask) {
+            return value_type{(entity & entity_mask) | (static_cast<entity_type>(version & version_mask) << length)};
+        } else {
+            return value_type{entity & entity_mask};
+        }
     }
 
     /**
@@ -144,7 +152,11 @@ public:
      * @return A properly constructed identifier.
      */
     [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept {
-        return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))};
+        if constexpr(Traits::version_mask) {
+            return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))};
+        } else {
+            return value_type{lhs & entity_mask};
+        }
     }
 };
 
@@ -314,7 +326,12 @@ struct tombstone_t {
     template<typename Entity>
     [[nodiscard]] constexpr bool operator==(const Entity entity) const noexcept {
         using traits_type = entt_traits<Entity>;
-        return traits_type::version_mask && (traits_type::to_version(entity) == traits_type::to_version(*this));
+
+        if constexpr(traits_type::version_mask) {
+            return (traits_type::to_version(entity) == traits_type::to_version(*this));
+        } else {
+            return false;
+        }
     }
 
     /**

+ 22 - 3
test/entt/entity/entity.cpp

@@ -13,17 +13,30 @@ struct entity_traits {
     static constexpr entity_type version_mask = 0x0FFF; // 12b
 };
 
+struct other_entity_traits {
+    using value_type = test::other_entity;
+    using entity_type = std::uint32_t;
+    using version_type = std::uint16_t;
+    static constexpr entity_type entity_mask = 0xFFFFFFFF; // 32b
+    static constexpr entity_type version_mask = 0x00;      // 0b
+};
+
 template<>
 struct entt::entt_traits<test::entity>: entt::basic_entt_traits<entity_traits> {
     static constexpr std::size_t page_size = ENTT_SPARSE_PAGE;
 };
 
+template<>
+struct entt::entt_traits<test::other_entity>: entt::basic_entt_traits<other_entity_traits> {
+    static constexpr std::size_t page_size = ENTT_SPARSE_PAGE;
+};
+
 template<typename Type>
 struct Entity: testing::Test {
     using type = Type;
 };
 
-using EntityTypes = ::testing::Types<entt::entity, test::entity>;
+using EntityTypes = ::testing::Types<entt::entity, test::entity, test::other_entity>;
 
 TYPED_TEST_SUITE(Entity, EntityTypes, );
 
@@ -42,13 +55,19 @@ TYPED_TEST(Entity, Traits) {
     ASSERT_NE(entt::to_integral(entity), entt::to_integral(entity_type{}));
 
     ASSERT_EQ(entt::to_entity(entity), 4u);
-    ASSERT_EQ(entt::to_version(entity), 1u);
+    ASSERT_EQ(entt::to_version(entity), !!traits_type::version_mask);
+
     ASSERT_EQ(entt::to_entity(other), 3u);
     ASSERT_EQ(entt::to_version(other), 0u);
 
     ASSERT_EQ(traits_type::construct(entt::to_entity(entity), entt::to_version(entity)), entity);
     ASSERT_EQ(traits_type::construct(entt::to_entity(other), entt::to_version(other)), other);
-    ASSERT_NE(traits_type::construct(entt::to_entity(entity), {}), entity);
+
+    if constexpr(traits_type::version_mask) {
+        ASSERT_NE(traits_type::construct(entt::to_entity(entity), entt::to_version(other)), entity);
+    } else {
+        ASSERT_EQ(traits_type::construct(entt::to_entity(entity), entt::to_version(other)), entity);
+    }
 
     ASSERT_EQ(traits_type::construct(entt::to_entity(other), entt::to_version(entity)), traits_type::combine(entt::to_integral(other), entt::to_integral(entity)));