From 48edf077fcb299301e148fc4406d24b143a2d790 Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Tue, 16 Feb 2021 10:44:03 +0100 Subject: [PATCH] sigh_storage_mixin: * Owner as template parameter (to make it reusable in other contexts) * Use storage payload for retrieving the owner from the storage --- src/entt/entity/poly_storage.hpp | 7 +++--- src/entt/entity/registry.hpp | 26 ++++++++++----------- src/entt/entity/storage.hpp | 39 ++++++++++++++++--------------- test/entt/entity/poly_storage.cpp | 28 +++++++++++----------- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/entt/entity/poly_storage.hpp b/src/entt/entity/poly_storage.hpp index 9b19b7507..61b080b90 100644 --- a/src/entt/entity/poly_storage.hpp +++ b/src/entt/entity/poly_storage.hpp @@ -20,7 +20,7 @@ namespace entt { template struct Storage: type_list< type_info() const ENTT_NOEXCEPT, - void(basic_registry &, const Entity *, const Entity *) + void(const Entity *, const Entity *) > { /*! @brief Underlying entity identifier. */ using entity_type = Entity; @@ -43,14 +43,13 @@ struct Storage: type_list< /** * @brief Removes entities from a storage. - * @param owner The registry that issued the request. * @param first An iterator to the first element of the range of * entities. * @param last An iterator past the last element of the range of * entities. */ - void remove(basic_registry &owner, const entity_type *first, const entity_type *last) { - poly_call<1>(*this, owner, first, last); + void remove(const entity_type *first, const entity_type *last) { + poly_call<1>(*this, first, last); } }; diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index ae66e8670..3c8f41f64 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -573,7 +573,7 @@ public: template decltype(auto) emplace(const entity_type entity, Args &&... args) { ENTT_ASSERT(valid(entity)); - return assure()->emplace(*this, entity, std::forward(args)...); + return assure()->emplace(entity, std::forward(args)...); } /** @@ -590,7 +590,7 @@ public: template void insert(It first, It last, const Component &value = {}) { ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); - assure()->insert(*this, first, last, value); + assure()->insert(first, last, value); } /** @@ -610,7 +610,7 @@ public: void insert(EIt first, EIt last, CIt from, CIt to) { static_assert(std::is_constructible_v::value_type>, "Invalid value type"); ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); - assure()->insert(*this, first, last, from, to); + assure()->insert(first, last, from, to); } /** @@ -639,8 +639,8 @@ public: auto *cpool = assure(); return cpool->contains(entity) - ? cpool->patch(*this, entity, [&args...](auto &curr) { curr = Component{std::forward(args)...}; }) - : cpool->emplace(*this, entity, std::forward(args)...); + ? cpool->patch(entity, [&args...](auto &curr) { curr = Component{std::forward(args)...}; }) + : cpool->emplace(entity, std::forward(args)...); } /** @@ -670,7 +670,7 @@ public: template decltype(auto) patch(const entity_type entity, Func &&... func) { ENTT_ASSERT(valid(entity)); - return assure()->patch(*this, entity, std::forward(func)...); + return assure()->patch(entity, std::forward(func)...); } /** @@ -692,7 +692,7 @@ public: */ template decltype(auto) replace(const entity_type entity, Args &&... args) { - return assure()->patch(*this, entity, [&args...](auto &curr) { curr = Component{std::forward(args)...}; }); + return assure()->patch(entity, [&args...](auto &curr) { curr = Component{std::forward(args)...}; }); } /** @@ -709,7 +709,7 @@ public: void remove(const entity_type entity) { ENTT_ASSERT(valid(entity)); static_assert(sizeof...(Component) > 0, "Provide one or more component types"); - (assure()->remove(*this, entity), ...); + (assure()->remove(entity), ...); } /** @@ -726,7 +726,7 @@ public: void remove(It first, It last) { ENTT_ASSERT(std::all_of(first, last, [this](const auto entity) { return valid(entity); })); static_assert(sizeof...(Component) > 0, "Provide one or more component types"); - (assure()->remove(*this, first, last), ...); + (assure()->remove(first, last), ...); } /** @@ -752,7 +752,7 @@ public: ENTT_ASSERT(valid(entity)); return ([this, entity](auto *cpool) { - return cpool->contains(entity) ? (cpool->remove(*this, entity), true) : false; + return cpool->contains(entity) ? (cpool->remove(entity), true) : false; }(assure()) + ... + size_type{}); } @@ -776,7 +776,7 @@ public: for(auto pos = pools.size(); pos; --pos) { if(auto &pdata = pools[pos-1]; pdata.pool && pdata.pool->contains(entity)) { - pdata.poly->remove(*this, std::begin(wrap), std::end(wrap)); + pdata.poly->remove(std::begin(wrap), std::end(wrap)); } } } @@ -874,7 +874,7 @@ public: [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&... args) { ENTT_ASSERT(valid(entity)); auto *cpool = assure(); - return cpool->contains(entity) ? cpool->get(entity) : cpool->emplace(*this, entity, std::forward(args)...); + return cpool->contains(entity) ? cpool->get(entity) : cpool->emplace(entity, std::forward(args)...); } /** @@ -926,7 +926,7 @@ public: each([this](const auto entity) { this->destroy(entity); }); } else { ([this](auto *cpool) { - cpool->remove(*this, cpool->basic_sparse_set::begin(), cpool->basic_sparse_set::end()); + cpool->remove(cpool->basic_sparse_set::begin(), cpool->basic_sparse_set::end()); }(assure()), ...); } } diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 1939b6104..133d7a75d 100644 --- a/src/entt/entity/storage.hpp +++ b/src/entt/entity/storage.hpp @@ -562,9 +562,15 @@ public: /** * @brief Mixin type to use to add signal support to storage types. * @tparam Type The type of the underlying storage. + * @tparam Owner Expected owner type. */ -template -struct sigh_storage_mixin: Type { +template +class sigh_storage_mixin: public Type { + Owner & owner() ENTT_NOEXCEPT { + return *static_cast(payload()); + } + +public: /*! @brief Underlying value type. */ using value_type = typename Type::value_type; /*! @brief Underlying entity identifier. */ @@ -640,15 +646,14 @@ struct sigh_storage_mixin: Type { /** * @copybrief storage_adapter_mixin::emplace * @tparam Args Types of arguments to use to construct the object. - * @param owner The registry that issued the request. * @param entity A valid entity identifier. * @param args Parameters to use to initialize the object. * @return A reference to the newly created object. */ template - decltype(auto) emplace(basic_registry &owner, const entity_type entity, Args &&... args) { + decltype(auto) emplace(const entity_type entity, Args &&... args) { Type::emplace(entity, std::forward(args)...); - construction.publish(owner, entity); + construction.publish(owner(), entity); if constexpr(!std::is_same_v) { return this->get(entity); @@ -660,45 +665,42 @@ struct sigh_storage_mixin: Type { * @tparam It Type of input iterator. * @tparam Args Types of arguments to use to construct the objects * associated with the entities. - * @param owner The registry that issued the request. * @param first An iterator to the first element of the range of entities. * @param last An iterator past the last element of the range of entities. * @param args Parameters to use to initialize the objects associated with * the entities. */ template - void insert(basic_registry &owner, It first, It last, Args &&... args) { + void insert(It first, It last, Args &&... args) { Type::insert(first, last, std::forward(args)...); if(!construction.empty()) { for(; first != last; ++first) { - construction.publish(owner, *first); + construction.publish(owner(), *first); } } } /** * @copybrief storage_adapter_mixin::remove - * @param owner The registry that issued the request. * @param entity A valid entity identifier. */ - void remove(basic_registry &owner, const entity_type entity) { - destruction.publish(owner, entity); + void remove(const entity_type entity) { + destruction.publish(owner(), entity); Type::remove(entity); } /** * @copybrief storage_adapter_mixin::remove * @tparam It Type of input iterator. - * @param owner The registry that issued the request. * @param first An iterator to the first element of the range of entities. * @param last An iterator past the last element of the range of entities. */ template - void remove(basic_registry &owner, It first, It last) { + void remove(It first, It last) { if(!destruction.empty()) { for(auto it = first; it != last; ++it) { - destruction.publish(owner, *it); + destruction.publish(owner(), *it); } } @@ -708,18 +710,17 @@ struct sigh_storage_mixin: Type { /** * @copybrief storage_adapter_mixin::patch * @tparam Func Types of the function objects to invoke. - * @param owner The registry that issued the request. * @param entity A valid entity identifier. * @param func Valid function objects. * @return A reference to the patched instance. */ template - decltype(auto) patch(basic_registry &owner, const entity_type entity, [[maybe_unused]] Func &&... func) { + decltype(auto) patch(const entity_type entity, [[maybe_unused]] Func &&... func) { if constexpr(std::is_same_v) { - update.publish(owner, entity); + update.publish(owner(), entity); } else { Type::patch(entity, std::forward(func)...); - update.publish(owner, entity); + update.publish(owner(), entity); return this->get(entity); } } @@ -747,7 +748,7 @@ private: template struct storage_traits { /*! @brief Resulting type after component-to-storage conversion. */ - using storage_type = sigh_storage_mixin>; + using storage_type = sigh_storage_mixin, entt::basic_registry>; }; diff --git a/test/entt/entity/poly_storage.cpp b/test/entt/entity/poly_storage.cpp index 3bad6ac34..76e80d3b3 100644 --- a/test/entt/entity/poly_storage.cpp +++ b/test/entt/entity/poly_storage.cpp @@ -11,9 +11,9 @@ template struct PolyStorage: entt::type_list_cat_t< decltype(as_type_list(std::declval>())), entt::type_list< - void(entt::basic_registry &, const Entity, const void *), + void(const Entity, const void *), const void *(const Entity) const, - void(const entt::basic_registry &, entt::basic_registry &) const + void(entt::basic_registry &) const > > { using entity_type = Entity; @@ -23,30 +23,30 @@ struct PolyStorage: entt::type_list_cat_t< struct type: entt::Storage::template type { static constexpr auto base = std::tuple_size_v>::type>; - void emplace(entt::basic_registry &owner, const entity_type entity, const void *instance) { - entt::poly_call(*this, owner, entity, instance); + void emplace(const entity_type entity, const void *instance) { + entt::poly_call(*this, entity, instance); } const void * get(const entity_type entity) const { return entt::poly_call(*this, entity); } - void copy(const entt::basic_registry &owner, entt::basic_registry &other) const { - entt::poly_call(*this, owner, other); + void copy_to(entt::basic_registry &other) const { + entt::poly_call(*this, other); } }; template struct members { - static void emplace(Type &self, entt::basic_registry &owner, const entity_type entity, const void *instance) { - self.emplace(owner, entity, *static_cast(instance)); + static void emplace(Type &self, const entity_type entity, const void *instance) { + self.emplace(entity, *static_cast(instance)); } static const typename Type::value_type * get(const Type &self, const entity_type entity) { return &self.get(entity); } - static void copy(const Type &self, const entt::basic_registry &owner, entt::basic_registry &other) { + static void copy_to(const Type &self, entt::basic_registry &other) { other.template insert(self.data(), self.data() + self.size(), self.raw(), self.raw() + self.size()); } }; @@ -57,7 +57,7 @@ struct PolyStorage: entt::type_list_cat_t< entt::value_list< &members::emplace, &members::get, - &members::copy + &members::copy_to > >; }; @@ -80,7 +80,7 @@ TEST(PolyStorage, CopyEntity) { registry.visit(entity, [&](const auto info) { auto &&storage = registry.storage(info); - storage->emplace(registry, other, storage->get(entity)); + storage->emplace(other, storage->get(entity)); }); ASSERT_TRUE((registry.all_of(entity))); @@ -103,7 +103,7 @@ TEST(PolyStorage, CopyRegistry) { ASSERT_EQ(other.size(), 0u); other.assign(registry.data(), registry.data() + registry.size(), registry.destroyed()); - registry.visit([&](const auto info) { std::as_const(registry).storage(info)->copy(registry, other); }); + registry.visit([&](const auto info) { std::as_const(registry).storage(info)->copy_to(other); }); ASSERT_EQ(registry.size(), other.size()); ASSERT_EQ((registry.view().size_hint()), (other.view().size_hint())); @@ -125,11 +125,11 @@ TEST(PolyStorage, Constness) { // cannot invoke remove on a const storage, let's copy the returned value auto cstorage = cregistry.storage(entt::type_id()); - ASSERT_DEATH(cstorage->remove(registry, std::begin(entity), std::end(entity)), ".*"); + ASSERT_DEATH(cstorage->remove(std::begin(entity), std::end(entity)), ".*"); ASSERT_TRUE(registry.all_of(entity[0])); auto &&storage = registry.storage(entt::type_id()); - storage->remove(registry, std::begin(entity), std::end(entity)); + storage->remove(std::begin(entity), std::end(entity)); ASSERT_FALSE(registry.all_of(entity[0])); }