storage: avoid emplacing extra entities when using a hint - close #1113
This commit is contained in:
@@ -952,8 +952,14 @@ class basic_storage<Entity, Entity, Allocator>
|
||||
using underlying_iterator = typename underlying_type::basic_iterator;
|
||||
|
||||
auto next() noexcept {
|
||||
ENTT_ASSERT(placeholder < underlying_type::traits_type::to_entity(null), "Invalid element");
|
||||
return underlying_type::traits_type::combine(static_cast<typename underlying_type::traits_type::entity_type>(placeholder++), {});
|
||||
entity_type entt = null;
|
||||
|
||||
do {
|
||||
ENTT_ASSERT(placeholder < underlying_type::traits_type::to_entity(null), "Invalid element");
|
||||
entt = underlying_type::traits_type::combine(static_cast<typename underlying_type::traits_type::entity_type>(placeholder++), {});
|
||||
} while(base_type::current(entt) != underlying_type::traits_type::to_version(tombstone));
|
||||
|
||||
return entt;
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -1079,15 +1085,7 @@ public:
|
||||
if(hint == null || hint == tombstone) {
|
||||
return emplace();
|
||||
} else if(const auto curr = underlying_type::traits_type::construct(underlying_type::traits_type::to_entity(hint), base_type::current(hint)); curr == tombstone) {
|
||||
const auto pos = static_cast<size_type>(underlying_type::traits_type::to_entity(hint));
|
||||
const auto entt = *base_type::try_emplace(hint, true);
|
||||
|
||||
for(; placeholder != pos;) {
|
||||
base_type::try_emplace(next(), false);
|
||||
}
|
||||
|
||||
placeholder = pos + 1u;
|
||||
return entt;
|
||||
return *base_type::try_emplace(hint, true);
|
||||
} else if(const auto idx = base_type::index(curr); idx < base_type::free_list()) {
|
||||
return emplace();
|
||||
} else {
|
||||
|
||||
@@ -280,14 +280,14 @@ TEST(SighMixin, StorageEntity) {
|
||||
|
||||
ASSERT_EQ(on_construct, 1u);
|
||||
ASSERT_EQ(on_destroy, 0u);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
ASSERT_EQ(pool.size(), 1u);
|
||||
ASSERT_EQ(pool.free_list(), 1u);
|
||||
|
||||
pool.erase(entt::entity{1});
|
||||
|
||||
ASSERT_EQ(on_construct, 1u);
|
||||
ASSERT_EQ(on_destroy, 1u);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
ASSERT_EQ(pool.size(), 1u);
|
||||
ASSERT_EQ(pool.free_list(), 0u);
|
||||
|
||||
pool.push(traits_type::construct(0, 2));
|
||||
|
||||
@@ -91,16 +91,16 @@ TEST(StorageEntity, Swap) {
|
||||
other.emplace(entt::entity{1});
|
||||
other.erase(entt::entity{2});
|
||||
|
||||
ASSERT_EQ(pool.size(), 5u);
|
||||
ASSERT_EQ(other.size(), 3u);
|
||||
ASSERT_EQ(pool.size(), 1u);
|
||||
ASSERT_EQ(other.size(), 2u);
|
||||
|
||||
pool.swap(other);
|
||||
|
||||
ASSERT_EQ(pool.type(), entt::type_id<void>());
|
||||
ASSERT_EQ(other.type(), entt::type_id<void>());
|
||||
|
||||
ASSERT_EQ(pool.size(), 3u);
|
||||
ASSERT_EQ(other.size(), 5u);
|
||||
ASSERT_EQ(pool.size(), 2u);
|
||||
ASSERT_EQ(other.size(), 1u);
|
||||
|
||||
ASSERT_EQ(pool.index(entt::entity{1}), 0u);
|
||||
ASSERT_EQ(other.index(entt::entity{4}), 0u);
|
||||
@@ -152,7 +152,7 @@ TEST(StorageEntity, Emplace) {
|
||||
ASSERT_LT(pool.index(entt::entity{2}), pool.free_list());
|
||||
ASSERT_LT(pool.index(entt::entity{3}), pool.free_list());
|
||||
ASSERT_LT(pool.index(entt::entity{4}), pool.free_list());
|
||||
ASSERT_GE(pool.index(entt::entity{5}), pool.free_list());
|
||||
ASSERT_EQ(pool.current(entt::entity{5}), traits_type::to_version(entt::tombstone));
|
||||
ASSERT_LT(pool.index(traits_type::construct(6, 3)), pool.free_list());
|
||||
|
||||
ASSERT_EQ(pool.emplace(traits_type::construct(5, 2)), traits_type::construct(5, 2));
|
||||
@@ -184,7 +184,7 @@ TEST(StorageEntity, TryEmplace) {
|
||||
ASSERT_LT(pool.index(entt::entity{1}), pool.free_list());
|
||||
ASSERT_LT(pool.index(entt::entity{2}), pool.free_list());
|
||||
ASSERT_LT(pool.index(entt::entity{3}), pool.free_list());
|
||||
ASSERT_GE(pool.index(entt::entity{4}), pool.free_list());
|
||||
ASSERT_EQ(pool.current(entt::entity{4}), traits_type::to_version(entt::tombstone));
|
||||
ASSERT_LT(pool.index(traits_type::construct(5, 3)), pool.free_list());
|
||||
|
||||
ASSERT_EQ(*pool.push(traits_type::construct(4, 2)), traits_type::construct(4, 2));
|
||||
@@ -265,9 +265,11 @@ TEST(StorageEntity, Insert) {
|
||||
|
||||
TEST(StorageEntity, Pack) {
|
||||
entt::storage<entt::entity> pool;
|
||||
std::array entity{entt::entity{1}, entt::entity{3}, entt::entity{4}};
|
||||
std::array entity{entt::entity{1}, entt::entity{3}, entt::entity{4}, entt::entity{2}};
|
||||
|
||||
pool.push(entity.begin(), entity.end());
|
||||
pool.erase(entity[3u]);
|
||||
|
||||
std::swap(entity[0u], entity[1u]);
|
||||
|
||||
const auto to = pool.sort_as(entity.begin() + 1u, entity.end());
|
||||
|
||||
Reference in New Issue
Block a user