From cf094e7ef5233bd2d23091f68d8d14f3870adbc3 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 29 Mar 2023 11:50:20 +0200 Subject: [PATCH] registry: finally split owning and non-owning groups as it ought to be --- src/entt/entity/group.hpp | 6 +--- src/entt/entity/registry.hpp | 61 ++++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/entt/entity/group.hpp b/src/entt/entity/group.hpp index a9fcc15da..900181cff 100644 --- a/src/entt/entity/group.hpp +++ b/src/entt/entity/group.hpp @@ -207,11 +207,7 @@ public: template group_handler(const Alloc &alloc, Get &...gpool, Exclude &...epool) - : basic_group_handler{ - sizeof...(Get) + sizeof...(Exclude), - +[](const id_type) noexcept { return false; }, - +[](const id_type ctype) noexcept { return ((ctype == entt::type_hash::value()) || ...); }, - +[]([[maybe_unused]] const id_type ctype) noexcept { return ((ctype == entt::type_hash::value()) || ...); }}, + : basic_group_handler{/* temporary, to be removed */}, pools{&gpool...}, filter{&epool...}, elem{alloc} { diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 98c287155..179e43d5e 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -326,7 +326,8 @@ public: basic_registry(const size_type count, const allocator_type &allocator = allocator_type{}) : vars{allocator}, pools{allocator}, - groups{allocator}, + owning_groups{allocator}, + non_owning_groups{allocator}, shortcut{&assure()} { pools.reserve(count); rebind(); @@ -339,7 +340,8 @@ public: basic_registry(basic_registry &&other) noexcept : vars{std::move(other.vars)}, pools{std::move(other.pools)}, - groups{std::move(other.groups)}, + owning_groups{std::move(other.owning_groups)}, + non_owning_groups{std::move(other.non_owning_groups)}, shortcut{std::move(other.shortcut)} { rebind(); } @@ -352,7 +354,8 @@ public: basic_registry &operator=(basic_registry &&other) noexcept { vars = std::move(other.vars); pools = std::move(other.pools); - groups = std::move(other.groups); + owning_groups = std::move(other.owning_groups); + non_owning_groups = std::move(other.non_owning_groups); shortcut = std::move(other.shortcut); rebind(); @@ -369,7 +372,8 @@ public: swap(vars, other.vars); swap(pools, other.pools); - swap(groups, other.groups); + swap(owning_groups, other.owning_groups); + swap(non_owning_groups, other.non_owning_groups); swap(shortcut, other.shortcut); rebind(); @@ -1204,18 +1208,22 @@ public: group(get_t = get_t{}, exclude_t = exclude_t{}) { using handler_type = typename basic_group...>, get_t...>, exclude_t...>>::handler; - if(auto it = groups.find(type_hash::value()); it != groups.cend()) { - return {static_cast(*it->second)}; - } - - std::shared_ptr handler{}; - if constexpr(sizeof...(Owned) == 0u) { - handler = std::allocate_shared(get_allocator(), get_allocator(), assure>()..., assure>()...); + if(auto it = non_owning_groups.find(type_hash::value()); it != non_owning_groups.cend()) { + return {static_cast(*it->second)}; + } + + auto handler = std::allocate_shared(get_allocator(), get_allocator(), assure>()..., assure>()...); + non_owning_groups.emplace(type_hash::value(), handler); + return {*handler}; } else { + if(auto it = owning_groups.find(type_hash::value()); it != owning_groups.cend()) { + return {static_cast(*it->second)}; + } + constexpr auto hsize = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude); - ENTT_ASSERT(std::all_of(groups.cbegin(), groups.cend(), [hsize](const auto &data) { + ENTT_ASSERT(std::all_of(owning_groups.cbegin(), owning_groups.cend(), [hsize](const auto &data) { const auto overlapping = (0u + ... + data.second->owned(type_hash>::value())); const auto sz = overlapping + (0u + ... + data.second->get(type_hash>::value())) + (0u + ... + data.second->exclude(type_hash>::value())); return !overlapping || ((sz == hsize) || (sz == data.second->size)); @@ -1225,7 +1233,7 @@ public: const internal::basic_group_handler *prev = nullptr; const internal::basic_group_handler *next = nullptr; - for(auto &&data: groups) { + for(auto &&data: owning_groups) { if((data.second->owned(type_hash>::value()) || ...)) { if(const auto sz = data.second->size; sz < hsize && (prev == nullptr || prev->size < sz)) { prev = data.second.get(); @@ -1237,12 +1245,10 @@ public: } } - handler = std::allocate_shared(get_allocator(), assure>()..., assure>()..., assure>()..., prev, next); + auto handler = std::allocate_shared(get_allocator(), assure>()..., assure>()..., assure>()..., prev, next); + owning_groups.emplace(type_hash::value(), handler); + return {*handler}; } - - groups.emplace(type_hash::value(), handler); - - return {*handler}; } /*! @copydoc group */ @@ -1251,11 +1257,17 @@ public: group_if_exists(get_t = get_t{}, exclude_t = exclude_t{}) const { using handler_type = typename basic_group...>, get_t...>, exclude_t...>>::handler; - if(auto it = groups.find(type_hash::value()); it == groups.cend()) { - return {}; + if constexpr(sizeof...(Owned) == 0u) { + if(auto it = non_owning_groups.find(type_hash::value()); it != non_owning_groups.cend()) { + return {static_cast(*it->second)}; + } } else { - return {static_cast(*it->second)}; + if(auto it = owning_groups.find(type_hash::value()); it != owning_groups.cend()) { + return {static_cast(*it->second)}; + } } + + return {}; } /** @@ -1266,7 +1278,7 @@ public: */ template [[nodiscard]] bool owned() const { - return std::any_of(groups.cbegin(), groups.cend(), [](auto &&data) { return (data.second->owned(type_hash>::value()) || ...); }); + return std::any_of(owning_groups.cbegin(), owning_groups.cend(), [](auto &&data) { return (data.second->owned(type_hash>::value()) || ...); }); } /** @@ -1280,7 +1292,7 @@ public: [[nodiscard]] bool sortable(const basic_group, get_t, exclude_t> &) noexcept { constexpr auto size = sizeof...(Owned) + sizeof...(Get) + sizeof...(Exclude); auto pred = [size](const auto &data) { return (data.second->owned(type_hash::value()) || ...) && (size < data.second->size); }; - return std::find_if(groups.cbegin(), groups.cend(), std::move(pred)) == groups.cend(); + return std::find_if(owning_groups.cbegin(), owning_groups.cend(), std::move(pred)) == owning_groups.cend(); } /** @@ -1372,7 +1384,8 @@ public: private: context vars; pool_container_type pools; - group_container_type groups; + group_container_type owning_groups; + group_container_type non_owning_groups; storage_for_type *shortcut; };