From 8a78b0dbd6f7c1be3a727cbb3a7f049058b5a978 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 1 Apr 2020 22:17:10 +0200 Subject: [PATCH] registry: use only sequential indexes for component types now --- src/entt/entity/registry.hpp | 36 +++++++++++++++--------------- test/entt/entity/registry.cpp | 42 ++++++++++++++++++++--------------- 2 files changed, 42 insertions(+), 36 deletions(-) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index ba584f61d..d1cbc8712 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -187,20 +187,18 @@ class basic_registry { template const pool_handler & assure() const { static_assert(std::is_same_v>); - static std::size_t index{pools.size()}; + const auto index = type_index::value(); - if(const auto length = pools.size(); !(index < length) || pools[index].type_id != type_info::id()) { - for(index = {}; index < length && pools[index].type_id != type_info::id(); ++index); + if(!(index < pools.size())) { + pools.resize(index+1); + } - if(index == length) { - pools.push_back(pool_data{ - type_info::id(), - std::unique_ptr>{new pool_handler()}, - [](sparse_set &cpool, basic_registry &owner, const entity_type entt) { - static_cast &>(cpool).remove(owner, entt); - } - }); - } + if(auto &&cpool = pools[index]; !cpool.pool) { + cpool.type_id = type_info::id(); + cpool.pool.reset(new pool_handler()); + cpool.remove = [](sparse_set &cpool, basic_registry &owner, const entity_type entt) { + static_cast &>(cpool).remove(owner, entt); + }; } return static_cast &>(*pools[index].pool); @@ -545,7 +543,7 @@ public: */ template void assign(It first, It last) { - ENTT_ASSERT(std::all_of(pools.cbegin(), pools.cend(), [](auto &&cpool) { return cpool.pool->empty(); })); + ENTT_ASSERT(std::all_of(pools.cbegin(), pools.cend(), [](auto &&pdata) { return !pdata.pool || pdata.pool->empty(); })); entities.assign(first, last); destroyed = null; @@ -582,7 +580,7 @@ public: ENTT_ASSERT(valid(entity)); for(auto pos = pools.size(); pos; --pos) { - if(auto &pdata = pools[pos-1]; pdata.pool->has(entity)) { + if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->has(entity)) { pdata.remove(*pdata.pool, *this, entity); } } @@ -1072,7 +1070,7 @@ public: */ bool orphan(const entity_type entity) const { ENTT_ASSERT(valid(entity)); - return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&pdata) { return pdata.pool->has(entity); }); + return std::none_of(pools.cbegin(), pools.cend(), [entity](auto &&pdata) { return pdata.pool && pdata.pool->has(entity); }); } /** @@ -1523,7 +1521,7 @@ public: std::vector *> selected(std::distance(first, last)); std::transform(first, last, selected.begin(), [this](const auto ctype) { - const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.type_id == ctype; }); + const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&pdata) { return pdata.pool && pdata.type_id == ctype; }); return it == pools.cend() ? nullptr : it->pool.get(); }); @@ -1624,7 +1622,7 @@ public: template void visit(entity_type entity, Func func) const { for(auto pos = pools.size(); pos; --pos) { - if(auto &pdata = pools[pos-1]; pdata.pool->has(entity)) { + if(const auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->has(entity)) { func(pdata.type_id); } } @@ -1653,7 +1651,9 @@ public: template void visit(Func func) const { for(auto pos = pools.size(); pos; --pos) { - func(pools[pos-1].type_id); + if(const auto &pdata = pools[pos-1]; pdata.pool) { + func(pdata.type_id); + } } } diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 13940fb9a..d3c8ed500 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1424,29 +1424,35 @@ TEST(Registry, Visit) { registry.assign(other); registry.assign(entity); - auto total = 0; - auto esize = 0; - auto osize = 0; + bool hasType[3]{}; - registry.visit([&total](const auto component) { - ASSERT_TRUE(total != 0 || component == entt::type_info::id()); - ASSERT_TRUE(total != 1 || component == entt::type_info::id()); - ASSERT_TRUE(total != 2 || component == entt::type_info::id()); - ++total; + registry.visit([&hasType](const auto component) { + hasType[0] = hasType[0] || (component == entt::type_info::id()); + hasType[1] = hasType[1] || (component == entt::type_info::id()); + hasType[2] = hasType[2] || (component == entt::type_info::id()); }); - registry.visit(entity, [&esize](const auto component) { - ASSERT_TRUE(esize != 0 || component == entt::type_info::id()); - ASSERT_TRUE(esize != 1 || component == entt::type_info::id()); - ++esize; + ASSERT_TRUE(hasType[0] && hasType[1] && hasType[2]); + + hasType[0] = hasType[1] = hasType[2] = false; + + registry.visit(entity, [&hasType](const auto component) { + hasType[0] = hasType[0] || (component == entt::type_info::id()); + hasType[1] = hasType[1] || (component == entt::type_info::id()); + hasType[2] = hasType[2] || (component == entt::type_info::id()); }); - registry.visit(other, [&osize](const auto component) { - ASSERT_TRUE(osize != 0 || component == entt::type_info::id()); - ++osize; + ASSERT_TRUE(hasType[0] && !hasType[1] && hasType[2]); + + hasType[0] = hasType[2] = false; + + registry.visit(other, [&hasType](const auto component) { + hasType[0] = hasType[0] || (component == entt::type_info::id()); + hasType[1] = hasType[1] || (component == entt::type_info::id()); + hasType[2] = hasType[2] || (component == entt::type_info::id()); }); - ASSERT_EQ(total, 3); - ASSERT_EQ(esize, 2); - ASSERT_EQ(osize, 1); + ASSERT_TRUE(!hasType[0] && hasType[1] && !hasType[2]); + + hasType[1] = false; }