From fba85754d732f7fd685ec12932afc5c752d7508a Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 6 Nov 2019 00:03:47 +0100 Subject: [PATCH] review: registry::clone --- TODO | 5 +---- src/entt/entity/registry.hpp | 43 ++++++++++++++---------------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/TODO b/TODO index b5202e112..f0b9d2020 100644 --- a/TODO +++ b/TODO @@ -23,7 +23,6 @@ - improves multi-stomp * range based registry::remove and some others? * add examples (and credits) from @alanjfs :) -* use [[nodiscard]] consistently for safety purposes * static reflection, hint: template<> meta_type_t: meta_descriptor * ENTT_NAMED_TYPE -> ENTT_EXPORT and add also ENTT_EXPORT_WITH_NAME * meta: members+class as fake functions, is it possible? @@ -36,7 +35,5 @@ * named types: almost-stable index optimization for direct access to pools, no more linear searches - can implicitly generate types for meta benefit from a similar approach? * multi component registry::remove and some others? - - remove create overload for spwaning - - clean up stomp functions - - review internal clone * get rid of registry::skip_family_pools +* registry::prepare is unsafe diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index b09469fcb..305911417 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -176,7 +176,7 @@ class basic_registry { struct pool_data { std::unique_ptr> pool; void(* remove)(sparse_set &, basic_registry &, const Entity); - std::unique_ptr>(* clone)(const sparse_set &); + void(* assure)(basic_registry &, const sparse_set &); const void *(* get)(const sparse_set &, const Entity); void(* set)(basic_registry &, const Entity, const void *); ENTT_ID_TYPE runtime_type; @@ -271,12 +271,12 @@ class basic_registry { }; if constexpr(std::is_copy_constructible_v>) { - pdata->clone = [](const sparse_set &cpool) -> std::unique_ptr> { - return std::make_unique>(static_cast &>(cpool)); + pdata->assure = [](basic_registry &other, const sparse_set &cpool) { + other.assure(static_cast &>(cpool)); }; - pdata->set = [](basic_registry &target, const Entity entt, const void *instance) { - target.assign_or_replace(entt, *static_cast *>(instance)); + pdata->set = [](basic_registry &other, const Entity entt, const void *instance) { + other.assign_or_replace(entt, *static_cast *>(instance)); }; } } @@ -1502,33 +1502,21 @@ public: */ template basic_registry clone(exclude_t = {}) const { - static_assert((sizeof...(Component) == 0 || sizeof...(Exclude) == 0) && std::conjunction_v...>); - basic_registry other; - other.pools.resize(pools.size()); - for(auto pos = pools.size(); pos; --pos) { - if(const auto &pdata = pools[pos-1]; pdata.pool && pdata.clone - && (!sizeof...(Component) || ... || (pdata.runtime_type == to_integer(type()))) - && ((pdata.runtime_type != to_integer(type())) && ...)) - { - auto &curr = other.pools[pos-1]; - curr.remove = pdata.remove; - curr.clone = pdata.clone; - curr.set = pdata.set; - curr.get = pdata.get; - curr.pool = pdata.clone(*pdata.pool); - curr.runtime_type = pdata.runtime_type; - } - } - - other.skip_family_pools = skip_family_pools; other.destroyed = destroyed; other.entities = entities; - other.pools.erase(std::remove_if(other.pools.begin()+skip_family_pools, other.pools.end(), [](const auto &pdata) { - return !pdata.pool; - }), other.pools.end()); + if constexpr(sizeof...(Component) == 0) { + for(auto pos = pools.size(); pos; --pos) { + if(const auto &pdata = pools[pos-1]; pdata.assure && ((pdata.runtime_type != to_integer(type())) && ...)) { + pdata.assure(other, *pdata.pool); + } + } + } else { + static_assert(sizeof...(Exclude) == 0 && std::conjunction_v...>); + (other.assure(*assure()), ...); + } return other; } @@ -1572,6 +1560,7 @@ public: } } } else { + static_assert(sizeof...(Exclude) == 0 && std::conjunction_v...>); (assign_or_replace(dst, other.get(src)), ...); } }