From d34e8298111b32b312639cc429ff0c010939e873 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 30 Aug 2019 16:23:42 +0200 Subject: [PATCH] perf improvement --- src/entt/entity/registry.hpp | 76 +++++++++++++++++------------------- 1 file changed, 36 insertions(+), 40 deletions(-) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 6be4b3978..3411aa586 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -46,13 +46,9 @@ class basic_registry { using component_family = family; using traits_type = entt_traits>; - struct group_type { - std::size_t owned{}; - }; - template struct pool_handler: storage { - group_type *group{}; + std::size_t *owned; pool_handler() ENTT_NOEXCEPT = default; @@ -130,8 +126,9 @@ class basic_registry { struct group_handler; template - struct group_handler, get_t>: sparse_set { - std::tuple *..., pool_type *...> cpools{}; + struct group_handler, get_t> { + const std::tuple *..., pool_type *...> cpools{}; + sparse_set set{}; template void maybe_valid_if(const Entity entt) { @@ -139,26 +136,28 @@ class basic_registry { if(((std::is_same_v || std::get *>(cpools)->has(entt)) && ...) && !(std::get *>(cpools)->has(entt) || ...)) { - this->construct(entt); + set.construct(entt); } } else if constexpr(std::disjunction_v...>) { if((std::get *>(cpools)->has(entt) && ...) - && ((std::is_same_v || !std::get *>(cpools)->has(entt)) && ...)) { - this->construct(entt); + && ((std::is_same_v || !std::get *>(cpools)->has(entt)) && ...)) + { + set.construct(entt); } } } void discard_if(const Entity entt) { - if(this->has(entt)) { - this->destroy(entt); + if(set.has(entt)) { + set.destroy(entt); } } }; template - struct group_handler, get_t, Owned...>: group_type { - std::tuple *..., pool_type *..., pool_type *...> cpools{}; + struct group_handler, get_t, Owned...> { + const std::tuple *..., pool_type *..., pool_type *...> cpools{}; + std::size_t owned{}; template void maybe_valid_if(const Entity entt) { @@ -1089,8 +1088,8 @@ public: */ template void sort(Compare compare, Sort algo = Sort{}, Args &&... args) { - if(auto *cpool = assure(); cpool->group) { - const auto last = cpool->end() - cpool->group->owned; + if(auto *cpool = assure(); cpool->owned) { + const auto last = cpool->end() - *cpool->owned; cpool->sort(cpool->begin(), last, std::move(compare), std::move(algo), std::forward(args)...); } else { cpool->sort(cpool->begin(), cpool->end(), std::move(compare), std::move(algo), std::forward(args)...); @@ -1329,7 +1328,7 @@ public: template bool owned() const ENTT_NOEXCEPT { const auto *cpool = pool(); - return cpool && cpool->group; + return cpool && cpool->owned; } /** @@ -1365,6 +1364,7 @@ public: static_assert(sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude) > 1); using handler_type = group_handler, get_t, Owned...>; + const auto cpools = std::make_tuple(assure()..., assure()..., assure()...); const std::size_t extent[3]{sizeof...(Owned), sizeof...(Get), sizeof...(Exclude)}; handler_type *curr = nullptr; @@ -1381,7 +1381,7 @@ public: if(!curr) { groups.push_back(group_data{ { sizeof...(Owned), sizeof...(Get), sizeof...(Exclude) }, - decltype(group_data::group){new handler_type{}, [](void *gptr) { delete static_cast(gptr); }}, + decltype(group_data::group){new handler_type{cpools}, [](void *gptr) { delete static_cast(gptr); }}, [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type()) || ...); }, [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type()) || ...); }, [](const component ctype) ENTT_NOEXCEPT { return ((ctype == type()) || ...); } @@ -1389,50 +1389,46 @@ public: curr = static_cast(groups.back().group.get()); - ((std::get *>(curr->cpools) = assure()), ...); - ((std::get *>(curr->cpools) = assure()), ...); - ((std::get *>(curr->cpools) = assure()), ...); + ENTT_ASSERT((!std::get *>(cpools)->owned && ...)); + ((std::get *>(cpools)->owned = &curr->owned), ...); - ENTT_ASSERT((!std::get *>(curr->cpools)->group && ...)); + (std::get *>(cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); - ((std::get *>(curr->cpools)->group = curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); + (std::get *>(cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::template maybe_valid_if>(*curr), ...); - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::discard_if>(*curr), ...); - - (std::get *>(curr->cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if>(*curr), ...); - (std::get *>(curr->cpools)->on_construct().template connect<&handler_type::discard_if>(*curr), ...); + (std::get *>(cpools)->on_destroy().template connect<&handler_type::template maybe_valid_if>(*curr), ...); + (std::get *>(cpools)->on_construct().template connect<&handler_type::discard_if>(*curr), ...); const auto *cpool = std::min({ - static_cast *>(std::get *>(curr->cpools))..., - static_cast *>(std::get *>(curr->cpools))... + static_cast *>(std::get *>(cpools))..., + static_cast *>(std::get *>(cpools))... }, [](const auto *lhs, const auto *rhs) { return lhs->size() < rhs->size(); }); // we cannot iterate backwards because we want to leave behind valid entities in case of owned types - std::for_each(cpool->data(), cpool->data() + cpool->size(), [curr](const auto entity) { - if((std::get *>(curr->cpools)->has(entity) && ...) - && (std::get *>(curr->cpools)->has(entity) && ...) - && !(std::get *>(curr->cpools)->has(entity) || ...)) + std::for_each(cpool->data(), cpool->data() + cpool->size(), [cpools, curr](const auto entity) { + if((std::get *>(cpools)->has(entity) && ...) + && (std::get *>(cpools)->has(entity) && ...) + && !(std::get *>(cpools)->has(entity) || ...)) { if constexpr(sizeof...(Owned) == 0) { - curr->construct(entity); + curr->set.construct(entity); } else { const auto pos = curr->owned++; // useless this-> used to suppress a warning with clang - (std::get *>(curr->cpools)->swap(std::get *>(curr->cpools)->index(entity), pos), ...); + (std::get *>(cpools)->swap(std::get *>(cpools)->index(entity), pos), ...); } } }); } if constexpr(sizeof...(Owned) == 0) { - return { static_cast *>(curr), std::get *>(curr->cpools)... }; + return { &curr->set, std::get *>(cpools)... }; } else { - return { &curr->owned, std::get *>(curr->cpools)... , std::get *>(curr->cpools)... }; + return { &curr->owned, std::get *>(cpools)... , std::get *>(cpools)... }; } }