Skip to content

Commit 3db20d0

Browse files
committed
entity: fully support reserved bits on identifiers
1 parent 9e62e1d commit 3db20d0

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/entt/entity/entity.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ class basic_entt_traits {
114114
* @return The integral representation of the version part.
115115
*/
116116
[[nodiscard]] static constexpr version_type to_version(const value_type value) noexcept {
117-
return static_cast<version_type>(to_integral(value) >> length);
117+
return (static_cast<version_type>(to_integral(value) >> length) & version_mask);
118118
}
119119

120120
/**
@@ -138,7 +138,7 @@ class basic_entt_traits {
138138
* @return A properly constructed identifier.
139139
*/
140140
[[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) noexcept {
141-
return value_type{(entity & entity_mask) | (static_cast<entity_type>(version) << length)};
141+
return value_type{(entity & entity_mask) | (static_cast<entity_type>(version & version_mask) << length)};
142142
}
143143

144144
/**
@@ -152,8 +152,7 @@ class basic_entt_traits {
152152
* @return A properly constructed identifier.
153153
*/
154154
[[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) noexcept {
155-
constexpr auto mask = (version_mask << length);
156-
return value_type{(lhs & entity_mask) | (rhs & mask)};
155+
return value_type{(lhs & entity_mask) | (rhs & (version_mask << length))};
157156
}
158157
};
159158

test/entt/entity/entity.cpp

+36-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct custom_entity_traits {
77
using entity_type = std::uint32_t;
88
using version_type = std::uint16_t;
99
static constexpr entity_type entity_mask = 0x3FFFF; // 18b
10-
static constexpr entity_type version_mask = 0x3FFF; // 14b
10+
static constexpr entity_type version_mask = 0x0FFF; // 12b
1111
};
1212

1313
template<>
@@ -57,6 +57,41 @@ TYPED_TEST(Entity, Traits) {
5757

5858
ASSERT_EQ(traits_type::next(entt::tombstone), traits_type::construct(entt::null, {}));
5959
ASSERT_EQ(traits_type::next(entt::null), traits_type::construct(entt::null, {}));
60+
61+
if constexpr(traits_type::to_integral(tombstone) != ~traits_type::entity_type{}) {
62+
// test reserved bits, if any
63+
constexpr entity_type reserved{traits_type::to_integral(entity) | (traits_type::to_integral(tombstone) + 1u)};
64+
65+
ASSERT_NE(reserved, entity);
66+
67+
ASSERT_NE(traits_type::to_integral(null), ~traits_type::entity_type{});
68+
ASSERT_NE(traits_type::to_integral(tombstone), ~traits_type::entity_type{});
69+
70+
ASSERT_EQ(traits_type::to_entity(reserved), traits_type::to_entity(entity));
71+
ASSERT_EQ(traits_type::to_version(reserved), traits_type::to_version(entity));
72+
73+
ASSERT_EQ(traits_type::to_version(null), traits_type::version_mask);
74+
ASSERT_EQ(traits_type::to_version(tombstone), traits_type::version_mask);
75+
76+
ASSERT_EQ(traits_type::to_version(traits_type::next(null)), 0u);
77+
ASSERT_EQ(traits_type::to_version(traits_type::next(tombstone)), 0u);
78+
79+
ASSERT_EQ(traits_type::construct(traits_type::to_integral(entity), traits_type::version_mask + 1u), entity_type{traits_type::to_entity(entity)});
80+
81+
ASSERT_EQ(traits_type::construct(traits_type::to_integral(null), traits_type::to_version(null) + 1u), entity_type{traits_type::to_entity(null)});
82+
ASSERT_EQ(traits_type::construct(traits_type::to_integral(tombstone), traits_type::to_version(tombstone) + 1u), entity_type{traits_type::to_entity(tombstone)});
83+
84+
ASSERT_EQ(traits_type::next(reserved), traits_type::next(entity));
85+
86+
ASSERT_EQ(traits_type::next(null), traits_type::combine(null, entity_type{}));
87+
ASSERT_EQ(traits_type::next(tombstone), traits_type::combine(tombstone, entity_type{}));
88+
89+
ASSERT_EQ(traits_type::combine(entity, reserved), entity);
90+
ASSERT_NE(traits_type::combine(entity, reserved), reserved);
91+
92+
ASSERT_EQ(traits_type::combine(reserved, entity), entity);
93+
ASSERT_NE(traits_type::combine(reserved, entity), reserved);
94+
}
6095
}
6196

6297
TYPED_TEST(Entity, Null) {

0 commit comments

Comments
 (0)