From 7a14fbb221d200c9d0afdbfe202fe3030290f92a Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Fri, 22 Nov 2019 00:04:59 +0100 Subject: [PATCH] registry: stomp doesn't work anymore with foreign registries --- src/entt/entity/registry.hpp | 48 ++++++++++------------------------- test/entt/entity/registry.cpp | 33 +++++------------------- 2 files changed, 20 insertions(+), 61 deletions(-) diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index 30a7fa1dc..38013f906 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -154,10 +154,9 @@ class basic_registry { struct pool_data { std::unique_ptr> pool; - void(* remove)(sparse_set &, basic_registry &, const Entity); void(* assure)(basic_registry &, const sparse_set &); - const void *(* get)(const sparse_set &, const Entity); - void(* set)(basic_registry &, const Entity, const void *); + void(* remove)(sparse_set &, basic_registry &, const Entity); + void(* stomp)(basic_registry &, const Entity, const sparse_set &, const Entity); ENTT_ID_TYPE runtime_type; }; @@ -245,21 +244,13 @@ class basic_registry { static_cast &>(cpool).remove(owner, entt); }; - pdata->get = [](const sparse_set &cpool, const Entity entt) -> const void * { - if constexpr(ENTT_ENABLE_ETO(Component)) { - return nullptr; - } else { - return static_cast &>(cpool).try_get(entt); - } - }; - if constexpr(std::is_copy_constructible_v>) { pdata->assure = [](basic_registry &other, const sparse_set &cpool) { other.assure(static_cast &>(cpool)); }; - pdata->set = [](basic_registry &other, const Entity entt, [[maybe_unused]] const void *instance) { - other.assign_or_replace(entt, instance ? *static_cast *>(instance) : std::decay_t{}); + pdata->stomp = [](basic_registry &other, const Entity dst, const sparse_set &cpool, const Entity src) { + other.assign_or_replace(dst, static_cast &>(cpool).get(src)); }; } } @@ -1513,11 +1504,11 @@ public: other.entities = entities; 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())) && ...)) { + std::for_each(pools.cbegin(), pools.cend(), [&other](const auto &pdata) { + if(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()), ...); @@ -1558,30 +1549,19 @@ public: * invalid entities. * * @tparam Component Types of components to copy. - * @tparam Entt A valid entity type (see entt_traits for more details). * @tparam Exclude Types of components not to be copied. * @param dst A valid entity identifier to copy to. - * @param src A valid entity identifier to be copied. * @param other The registry that owns the source entity. + * @param src A valid entity identifier to be copied. */ - template - void stomp(const entity_type dst, const Entt src, const basic_registry &other, exclude_t = {}) { + template + void stomp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t = {}) { if constexpr(sizeof...(Component) == 0) { - for(auto pos = other.pools.size(); pos; --pos) { - if(const auto &pdata = other.pools[pos-1]; pdata.set && ((pdata.runtime_type != to_integer(type())) && ...) && pdata.pool->has(src)) { - if constexpr(std::is_same_v) { - pdata.set(*this, dst, pdata.get(*pdata.pool, src)); - } else { - if(const auto ctype = pdata.runtime_type; ctype < pools.size() && pools[ctype].pool && pools[ctype].runtime_type == ctype) { - pools[ctype].set(*this, dst, pdata.get(*pdata.pool, src)); - } else { - const auto it = std::find_if(pools.cbegin(), pools.cend(), [ctype](auto &&curr) { return curr.pool && curr.runtime_type == ctype; }); - ENTT_ASSERT(it != pools.cend()); - it->set(*this, dst, pdata.get(*pdata.pool, src)); - } - } + std::for_each(other.pools.cbegin(), other.pools.cend(), [this, dst, src](const auto &pdata) { + if(pdata.stomp && ((pdata.runtime_type != to_integer(type())) && ...) && pdata.pool->has(src)) { + pdata.stomp(*this, dst, *pdata.pool, src); } - } + }); } else { static_assert(sizeof...(Exclude) == 0 && std::conjunction_v...>); (assign_or_replace(dst, other.template get(src)), ...); diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 33550f33b..1ee8b71c1 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1474,7 +1474,7 @@ TEST(Registry, Stomp) { registry.assign(prototype, 'c'); auto entity = registry.create(); - registry.stomp(entity, prototype, registry); + registry.stomp(entity, registry, prototype); ASSERT_TRUE((registry.has(entity))); ASSERT_EQ(registry.get(entity), 3); @@ -1482,7 +1482,7 @@ TEST(Registry, Stomp) { registry.replace(prototype, 42); registry.replace(prototype, 'a'); - registry.stomp(entity, prototype, registry); + registry.stomp(entity, registry, prototype); ASSERT_EQ(registry.get(entity), 42); ASSERT_EQ(registry.get(entity), 'c'); @@ -1497,21 +1497,21 @@ TEST(Registry, StompExclude) { registry.assign(prototype); const auto entity = registry.create(); - registry.stomp(entity, prototype, registry, entt::exclude); + registry.stomp(entity, registry, prototype, entt::exclude); ASSERT_TRUE((registry.has(entity))); ASSERT_FALSE(registry.has(entity)); ASSERT_EQ(registry.get(entity), 3); registry.replace(prototype, 42); - registry.stomp(entity, prototype, registry, entt::exclude); + registry.stomp(entity, registry, prototype, entt::exclude); ASSERT_TRUE((registry.has(entity))); ASSERT_EQ(registry.get(entity), 3); ASSERT_EQ(registry.get(entity), 'c'); registry.remove(entity); - registry.stomp(entity, prototype, registry, entt::exclude); + registry.stomp(entity, registry, prototype, entt::exclude); ASSERT_TRUE(registry.orphan(entity)); } @@ -1524,33 +1524,12 @@ TEST(Registry, StompMoveOnlyComponent) { registry.assign(prototype); const auto entity = registry.create(); - registry.stomp(entity, prototype, registry); + registry.stomp(entity, registry, prototype); ASSERT_TRUE(registry.has(entity)); ASSERT_FALSE(registry.has>(entity)); } -TEST(Registry, StompBetweenRegistriesWithDifferentIdentifiers) { - entt::basic_registry source; - entt::registry destination; - - const auto entity = source.create(); - const auto other = destination.create(); - - source.assign(entity, 'c'); - source.assign(entity, 0.); - source.assign(entity, 42); - - destination.prepare(); - destination.prepare(); - destination.stomp(other, entity, source, entt::exclude); - - ASSERT_TRUE((destination.has(other))); - ASSERT_FALSE(destination.has(other)); - ASSERT_EQ(destination.get(other), 'c'); - ASSERT_EQ(destination.get(other), 42); -} - TEST(Registry, GetOrAssign) { entt::registry registry; const auto entity = registry.create();