From e376a53b095f878d71bb1967223c03952a254cda Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Sat, 13 Nov 2021 12:04:17 +0100 Subject: [PATCH] entity: * custom move ctor/op for the registry class * no registry argument from storage emplace, remove, ... * added sparse set context to forward variables to mixins * removed sparse set user data --- TODO | 1 + src/entt/entity/registry.hpp | 69 +++++++++---- src/entt/entity/sparse_set.hpp | 76 +++++--------- src/entt/entity/storage.hpp | 126 +++++++----------------- test/entt/entity/poly_storage.cpp | 22 ++--- test/entt/entity/sigh_storage_mixin.cpp | 54 +++++----- test/entt/entity/sparse_set.cpp | 31 +----- test/entt/entity/view.cpp | 6 +- test/example/signal_less.cpp | 2 +- 9 files changed, 157 insertions(+), 230 deletions(-) diff --git a/TODO b/TODO index a0ec2d1b2..eeab15b58 100644 --- a/TODO +++ b/TODO @@ -4,6 +4,7 @@ * add examples (and credits) from @alanjfs :) WIP: +* remove the const_cast within registry::assure (view vs view, thread safe const registry) * fast-contains for sparse sets (low prio but nice-to-have) * runtime components (registry), runtime events (dispatcher/emitter), runtime context variables ... * runtime_view/registry, remove reference to basic_sparse_set diff --git a/src/entt/entity/registry.hpp b/src/entt/entity/registry.hpp index c50902e40..d64d9c51b 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -110,6 +110,7 @@ class basic_registry { if(auto &&pdata = pools[type_id().hash()]; !pdata.pool) { auto *cpool = new storage_type{}; pdata.pool.reset(cpool); + pdata.pool->context(forward_as_any(const_cast(*this))); pdata.poly.template emplace &>(*static_cast *>(pdata.pool.get())); return cpool; } else { @@ -156,11 +157,39 @@ public: /*! @brief Default constructor. */ basic_registry() = default; - /*! @brief Default move constructor. */ - basic_registry(basic_registry &&) = default; + /** + * @brief Move constructor. + * @param other The instance to move from. + */ + basic_registry(basic_registry &&other) ENTT_NOEXCEPT + : pools{std::move(other.pools)}, + vars{std::move(other.vars)}, + groups{std::move(other.groups)}, + entities{std::move(other.entities)}, + free_list{other.free_list} { + for(auto &&pdata: pools) { + pdata.second.pool->context(forward_as_any(*this)); + } + } - /*! @brief Default move assignment operator. @return This registry. */ - basic_registry &operator=(basic_registry &&) = default; + /** + * @brief Move assignment operator. + * @param other The instance to move from. + * @return This registry. + */ + basic_registry &operator=(basic_registry &&other) ENTT_NOEXCEPT { + pools = std::move(other.pools); + vars = std::move(other.vars); + groups = std::move(other.groups); + entities = std::move(other.entities); + free_list = other.free_list; + + for(auto &&pdata: pools) { + pdata.second.pool->context(forward_as_any(*this)); + } + + return *this; + } /** * @brief Prepares a pool for the given type if required. @@ -519,7 +548,7 @@ public: ENTT_ASSERT(valid(entity), "Invalid entity"); for(auto &&pdata: pools) { - pdata.second.pool->remove(entity, this); + pdata.second.pool->remove(entity); } return release_entity(entity, version); @@ -542,7 +571,7 @@ public: } } else { for(auto &&pdata: pools) { - pdata.second.pool->remove(first, last, this); + pdata.second.pool->remove(first, last); } release(first, last); @@ -569,7 +598,7 @@ public: template decltype(auto) emplace(const entity_type entity, Args &&...args) { ENTT_ASSERT(valid(entity), "Invalid entity"); - return assure()->emplace(*this, entity, std::forward(args)...); + return assure()->emplace(entity, std::forward(args)...); } /** @@ -586,7 +615,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); }), "Invalid entity"); - assure()->insert(*this, first, last, value); + assure()->insert(first, last, value); } /** @@ -605,7 +634,7 @@ public: void insert(EIt first, EIt last, CIt from) { 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); }), "Invalid entity"); - assure()->insert(*this, first, last, from); + assure()->insert(first, last, from); } /** @@ -626,8 +655,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)...); } /** @@ -657,7 +686,7 @@ public: template decltype(auto) patch(const entity_type entity, Func &&...func) { ENTT_ASSERT(valid(entity), "Invalid entity"); - return assure()->patch(*this, entity, std::forward(func)...); + return assure()->patch(entity, std::forward(func)...); } /** @@ -679,7 +708,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)...}), ...); }); } /** @@ -696,7 +725,7 @@ public: size_type remove(const entity_type entity) { ENTT_ASSERT(valid(entity), "Invalid entity"); static_assert(sizeof...(Component) > 0, "Provide one or more component types"); - return (assure()->remove(entity, this) + ... + size_type{}); + return (assure()->remove(entity) + ... + size_type{}); } /** @@ -719,7 +748,7 @@ public: for(; first != last; ++first) { const auto entity = *first; ENTT_ASSERT(valid(entity), "Invalid entity"); - count += (std::get *>(cpools)->remove(entity, this) + ...); + count += (std::get *>(cpools)->remove(entity) + ...); } return count; @@ -739,7 +768,7 @@ public: void erase(const entity_type entity) { ENTT_ASSERT(valid(entity), "Invalid entity"); static_assert(sizeof...(Component) > 0, "Provide one or more component types"); - (assure()->erase(entity, this), ...); + (assure()->erase(entity), ...); } /** @@ -760,7 +789,7 @@ public: for(; first != last; ++first) { const auto entity = *first; ENTT_ASSERT(valid(entity), "Invalid entity"); - (std::get *>(cpools)->erase(entity, this), ...); + (std::get *>(cpools)->erase(entity), ...); } } @@ -868,7 +897,7 @@ public: [[nodiscard]] decltype(auto) get_or_emplace(const entity_type entity, Args &&...args) { ENTT_ASSERT(valid(entity), "Invalid 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)...); } /** @@ -916,12 +945,12 @@ public: void clear() { if constexpr(sizeof...(Component) == 0) { for(auto &&pdata: pools) { - pdata.second.pool->clear(this); + pdata.second.pool->clear(); } each([this](const auto entity) { release_entity(entity, entity_traits::to_version(entity) + 1u); }); } else { - (assure()->clear(this), ...); + (assure()->clear(), ...); } } diff --git a/src/entt/entity/sparse_set.hpp b/src/entt/entity/sparse_set.hpp index 78163f329..18c117adf 100644 --- a/src/entt/entity/sparse_set.hpp +++ b/src/entt/entity/sparse_set.hpp @@ -9,6 +9,7 @@ #include #include "../config/config.h" #include "../core/algorithm.hpp" +#include "../core/any.hpp" #include "../core/memory.hpp" #include "entity.hpp" #include "fwd.hpp" @@ -207,7 +208,7 @@ protected: * @brief Erase an entity from a sparse set. * @param entt A valid identifier. */ - virtual void swap_and_pop(const Entity entt, void *) { + virtual void swap_and_pop(const Entity entt) { auto &ref = sparse_ref(entt); const auto pos = static_cast(entity_traits::to_entity(ref)); ENTT_ASSERT(packed[pos] == entt, "Invalid identifier"); @@ -226,7 +227,7 @@ protected: * @brief Erase an entity from a sparse set. * @param entt A valid identifier. */ - virtual void in_place_pop(const Entity entt, void *) { + virtual void in_place_pop(const Entity entt) { auto &ref = sparse_ref(entt); const auto pos = static_cast(entity_traits::to_entity(ref)); ENTT_ASSERT(packed[pos] == entt, "Invalid identifier"); @@ -240,7 +241,7 @@ protected: * @brief Assigns an entity to a sparse set. * @param entt A valid identifier. */ - virtual void try_emplace(const Entity entt, void *) { + virtual void try_emplace(const Entity entt) { const auto pos = static_cast(entity_traits::to_entity(entt)); const auto page = pos / sparse_page_v; @@ -301,7 +302,6 @@ public: explicit basic_sparse_set(deletion_policy pol, const allocator_type &allocator = {}) : sparse{allocator}, packed{allocator}, - udata{}, free_list{tombstone}, mode{pol} {} @@ -312,7 +312,6 @@ public: basic_sparse_set(basic_sparse_set &&other) ENTT_NOEXCEPT : sparse{std::move(other.sparse)}, packed{std::move(other.packed)}, - udata{std::exchange(other.udata, nullptr)}, free_list{std::exchange(other.free_list, tombstone)}, mode{other.mode} {} @@ -324,7 +323,6 @@ public: basic_sparse_set(basic_sparse_set &&other, const allocator_type &allocator) ENTT_NOEXCEPT : sparse{std::move(other.sparse), allocator}, packed{std::move(other.packed), allocator}, - udata{std::exchange(other.udata, nullptr)}, free_list{std::exchange(other.free_list, tombstone)}, mode{other.mode} { ENTT_ASSERT(alloc_traits::is_always_equal::value || packed.get_allocator() == other.packed.get_allocator(), "Copying a sparse set is not allowed"); @@ -346,7 +344,6 @@ public: release_sparse_pages(); sparse = std::move(other.sparse); packed = std::move(other.packed); - udata = std::exchange(other.udata, nullptr); free_list = std::exchange(other.free_list, tombstone); mode = other.mode; return *this; @@ -361,7 +358,6 @@ public: swap_contents(other); swap(sparse, other.sparse); swap(packed, other.packed); - swap(udata, other.udata); swap(free_list, other.free_list); swap(mode, other.mode); } @@ -592,10 +588,9 @@ public: * results in undefined behavior. * * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. */ - void emplace(const entity_type entt, void *ud = nullptr) { - try_emplace(entt, ud); + void emplace(const entity_type entt) { + try_emplace(entt); ENTT_ASSERT(contains(entt), "Emplace did not take place"); } @@ -609,18 +604,17 @@ public: * @tparam It Type of input iterator. * @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 ud Optional user data that are forwarded as-is to derived classes. */ template - void insert(It first, It last, void *ud = nullptr) { + void insert(It first, It last) { for(; first != last && free_list != null; ++first) { - emplace(*first, ud); + emplace(*first); } reserve(packed.size() + std::distance(first, last)); for(; first != last; ++first) { - emplace(*first, ud); + emplace(*first); } } @@ -632,11 +626,10 @@ public: * results in undefined behavior. * * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. */ - void erase(const entity_type entt, void *ud = nullptr) { + void erase(const entity_type entt) { ENTT_ASSERT(contains(entt), "Set does not contain entity"); - (mode == deletion_policy::in_place) ? in_place_pop(entt, ud) : swap_and_pop(entt, ud); + (mode == deletion_policy::in_place) ? in_place_pop(entt) : swap_and_pop(entt); ENTT_ASSERT(!contains(entt), "Destruction did not take place"); } @@ -648,23 +641,21 @@ public: * @tparam It Type of input iterator. * @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 ud Optional user data that are forwarded as-is to derived classes. */ template - void erase(It first, It last, void *ud = nullptr) { + void erase(It first, It last) { for(; first != last; ++first) { - erase(*first, ud); + erase(*first); } } /** * @brief Removes an entity from a sparse set if it exists. * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. * @return True if the entity is actually removed, false otherwise. */ - bool remove(const entity_type entt, void *ud = nullptr) { - return contains(entt) && (erase(entt, ud), true); + bool remove(const entity_type entt) { + return contains(entt) && (erase(entt), true); } /** @@ -672,15 +663,14 @@ public: * @tparam It Type of input iterator. * @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 ud Optional user data that are forwarded as-is to derived classes. * @return The number of entities actually removed. */ template - size_type remove(It first, It last, void *ud = nullptr) { + size_type remove(It first, It last) { size_type found{}; for(; first != last; ++first) { - found += remove(*first, ud); + found += remove(*first); } return found; @@ -840,42 +830,20 @@ public: } } - /** - * @brief Clears a sparse set. - * @param ud Optional user data that are forwarded as-is to derived classes. - */ - void clear(void *ud = nullptr) { + /*! @brief Clears a sparse set. */ + void clear() { for(auto &&entity: *this) { // honor the modality and filter all tombstones - remove(entity, ud); + remove(entity); } } - /** - * @brief User defined arbitrary data. - * @return An opaque pointer to user defined arbitrary data. - */ - void *user_data() ENTT_NOEXCEPT { - return udata; - } - - /*! @copydoc user_data */ - const void *user_data() const ENTT_NOEXCEPT { - return udata; - } - - /** - * @brief User defined arbitrary data. - * @param ptr An opaque pointer to user defined arbitrary data. - */ - void user_data(void *ptr) ENTT_NOEXCEPT { - udata = ptr; - } + /*! @brief Forwards context variables to mixins, if any. */ + virtual void context(any) ENTT_NOEXCEPT {} private: sparse_container_type sparse; packed_container_type packed; - void *udata; entity_type free_list; deletion_policy mode; }; diff --git a/src/entt/entity/storage.hpp b/src/entt/entity/storage.hpp index 050e20591..c8e30f79d 100644 --- a/src/entt/entity/storage.hpp +++ b/src/entt/entity/storage.hpp @@ -10,6 +10,7 @@ #include #include "../config/config.h" #include "../core/algorithm.hpp" +#include "../core/any.hpp" #include "../core/compressed_pair.hpp" #include "../core/memory.hpp" #include "../core/type_traits.hpp" @@ -316,9 +317,8 @@ protected: /** * @brief Erase an element from a storage. * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. */ - void swap_and_pop(const Entity entt, void *ud) override { + void swap_and_pop(const Entity entt) override { const auto pos = base_type::index(entt); const auto last = base_type::size() - 1u; @@ -330,17 +330,16 @@ protected: target = std::move(elem); std::destroy_at(std::addressof(elem)); - base_type::swap_and_pop(entt, ud); + base_type::swap_and_pop(entt); } /** * @brief Erases an element from a storage. * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. */ - void in_place_pop(const Entity entt, void *ud) override { + void in_place_pop(const Entity entt) override { const auto pos = base_type::index(entt); - base_type::in_place_pop(entt, ud); + base_type::in_place_pop(entt); // support for nosy destructors std::destroy_at(std::addressof(element_at(pos))); } @@ -348,15 +347,14 @@ protected: /** * @brief Assigns an entity to a storage. * @param entt A valid identifier. - * @param ud Optional user data that are forwarded as-is to derived classes. */ - void try_emplace([[maybe_unused]] const Entity entt, [[maybe_unused]] void *ud) override { + void try_emplace([[maybe_unused]] const Entity entt) override { if constexpr(std::is_default_constructible_v) { const auto pos = base_type::slot(); construct(assure_at_least(pos)); ENTT_TRY { - base_type::try_emplace(entt, ud); + base_type::try_emplace(entt); ENTT_ASSERT(pos == base_type::index(entt), "Misplaced component"); } ENTT_CATCH { @@ -648,7 +646,7 @@ public: construct(elem, std::forward(args)...); ENTT_TRY { - base_type::try_emplace(entt, nullptr); + base_type::try_emplace(entt); ENTT_ASSERT(pos == base_type::index(entt), "Misplaced component"); } ENTT_CATCH { @@ -814,7 +812,7 @@ public: template void emplace(const entity_type entt, Args &&...args) { [[maybe_unused]] const value_type elem{std::forward(args)...}; - base_type::try_emplace(entt, nullptr); + base_type::try_emplace(entt); } /** @@ -850,62 +848,6 @@ public: } }; -/** - * @brief Mixin type to use to wrap basic storage classes. - * @tparam Type The type of the underlying storage. - */ -template -struct storage_adapter_mixin: Type { - static_assert(std::is_same_v>, "Invalid object type"); - - /*! @brief Type of the objects assigned to entities. */ - using value_type = typename Type::value_type; - /*! @brief Underlying entity identifier. */ - using entity_type = typename Type::entity_type; - - /*! @brief Inherited constructors. */ - using Type::Type; - - /** - * @brief Assigns entities to a storage. - * @tparam Args Types of arguments to use to construct the object. - * @param entt A valid identifier. - * @param args Parameters to use to initialize the object. - * @return A reference to the newly created object. - */ - template - decltype(auto) emplace(basic_registry &, const entity_type entt, Args &&...args) { - return Type::emplace(entt, std::forward(args)...); - } - - /** - * @brief Patches the given instance for an entity. - * @tparam Func Types of the function objects to invoke. - * @param entt A valid identifier. - * @param func Valid function objects. - * @return A reference to the patched instance. - */ - template - decltype(auto) patch(basic_registry &, const entity_type entt, Func &&...func) { - return Type::patch(entt, std::forward(func)...); - } - - /** - * @brief Assigns entities to a storage. - * @tparam It Type of input iterator. - * @tparam Args Types of arguments to use to construct the objects assigned - * to the entities. - * @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 assigned to the - * entities. - */ - template - void insert(basic_registry &, It first, It last, Args &&...args) { - Type::insert(std::move(first), std::move(last), std::forward(args)...); - } -}; - /** * @brief Mixin type to use to add signal support to storage types. * @tparam Type The type of the underlying storage. @@ -913,24 +855,24 @@ struct storage_adapter_mixin: Type { template class sigh_storage_mixin final: public Type { /*! @copydoc basic_sparse_set::swap_and_pop */ - void swap_and_pop(const typename Type::entity_type entt, void *ud) final { - ENTT_ASSERT(ud != nullptr, "Invalid pointer to registry"); - destruction.publish(*static_cast *>(ud), entt); - Type::swap_and_pop(entt, ud); + void swap_and_pop(const typename Type::entity_type entt) final { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + destruction.publish(*owner, entt); + Type::swap_and_pop(entt); } /*! @copydoc basic_sparse_set::in_place_pop */ - void in_place_pop(const typename Type::entity_type entt, void *ud) final { - ENTT_ASSERT(ud != nullptr, "Invalid pointer to registry"); - destruction.publish(*static_cast *>(ud), entt); - Type::in_place_pop(entt, ud); + void in_place_pop(const typename Type::entity_type entt) final { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + destruction.publish(*owner, entt); + Type::in_place_pop(entt); } /*! @copydoc basic_sparse_set::try_emplace */ - void try_emplace(const typename Type::entity_type entt, void *ud) final { - ENTT_ASSERT(ud != nullptr, "Invalid pointer to registry"); - Type::try_emplace(entt, ud); - construction.publish(*static_cast *>(ud), entt); + void try_emplace(const typename Type::entity_type entt) final { + ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry"); + Type::try_emplace(entt); + construction.publish(*owner, entt); } public: @@ -1010,30 +952,28 @@ public: /** * @brief Assigns entities to a storage. * @tparam Args Types of arguments to use to construct the object. - * @param owner The registry that issued the request. * @param entt A valid 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 entt, Args &&...args) { + decltype(auto) emplace(const entity_type entt, Args &&...args) { Type::emplace(entt, std::forward(args)...); - construction.publish(owner, entt); + construction.publish(*owner, entt); return this->get(entt); } /** * @brief Patches the given instance for an entity. * @tparam Func Types of the function objects to invoke. - * @param owner The registry that issued the request. * @param entt A valid identifier. * @param func Valid function objects. * @return A reference to the patched instance. */ template - decltype(auto) patch(basic_registry &owner, const entity_type entt, Func &&...func) { + decltype(auto) patch(const entity_type entt, Func &&...func) { Type::patch(entt, std::forward(func)...); - update.publish(owner, entt); + update.publish(*owner, entt); return this->get(entt); } @@ -1042,27 +982,37 @@ public: * @tparam It Type of input iterator. * @tparam Args Types of arguments to use to construct the objects assigned * to 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 assigned to 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); } } } + /** + * @brief Forwards context variables to mixins, if any. + * @param value A context variable wrapped in an opaque container. + */ + void context(any value) ENTT_NOEXCEPT final { + auto *reg = any_cast>(&value); + owner = reg ? reg : owner; + Type::context(std::move(value)); + } + private: sigh &, const entity_type)> construction{}; sigh &, const entity_type)> destruction{}; sigh &, const entity_type)> update{}; + basic_registry *owner{}; }; /** diff --git a/test/entt/entity/poly_storage.cpp b/test/entt/entity/poly_storage.cpp index b8b77dc95..9afe7d389 100644 --- a/test/entt/entity/poly_storage.cpp +++ b/test/entt/entity/poly_storage.cpp @@ -12,8 +12,8 @@ struct PolyStorage : entt::type_list_cat_t< decltype(as_type_list(std::declval>())), entt::type_list< - void(const Entity *, const Entity *, void *), - void(entt::basic_registry &, const Entity, const void *), + void(const Entity *, const Entity *), + void(const Entity, const void *), const void *(const Entity) const, void(entt::basic_registry &) const>> { using entity_type = Entity; @@ -23,12 +23,12 @@ struct PolyStorage struct type: entt::Storage::template type { static constexpr auto base = decltype(as_type_list(std::declval>()))::size; - void erase(entt::basic_registry &owner, const entity_type *first, const entity_type *last) { - entt::poly_call(*this, first, last, &owner); + void erase(const entity_type *first, const entity_type *last) { + entt::poly_call(*this, first, last); } - 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 { @@ -42,8 +42,8 @@ struct PolyStorage 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) { @@ -84,7 +84,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))); @@ -129,11 +129,11 @@ TEST(PolyStorage, Constness) { // cannot invoke erase on a const storage, let's copy the returned value auto cstorage = cregistry.storage(entt::type_id()); - ASSERT_DEATH(cstorage->erase(registry, std::begin(entity), std::end(entity)), ""); + ASSERT_DEATH(cstorage->erase(std::begin(entity), std::end(entity)), ""); ASSERT_TRUE(registry.all_of(entity[0])); auto &&storage = registry.storage(entt::type_id()); - storage->erase(registry, std::begin(entity), std::end(entity)); + storage->erase(std::begin(entity), std::end(entity)); ASSERT_FALSE(registry.all_of(entity[0])); } diff --git a/test/entt/entity/sigh_storage_mixin.cpp b/test/entt/entity/sigh_storage_mixin.cpp index 1edc624d6..83296a229 100644 --- a/test/entt/entity/sigh_storage_mixin.cpp +++ b/test/entt/entity/sigh_storage_mixin.cpp @@ -39,14 +39,16 @@ TEST(SighStorageMixin, GenericType) { entt::entity entities[2u]{entt::entity{3}, entt::entity{42}}; entt::registry registry{}; + pool.context(entt::forward_as_any(registry)); + counter on_construct{}; counter on_destroy{}; pool.on_construct().connect<&listener>(on_construct); pool.on_destroy().connect<&listener>(on_destroy); - base.emplace(entities[0u], ®istry); - pool.emplace(registry, entities[1u]); + base.emplace(entities[0u]); + pool.emplace(entities[1u]); ASSERT_EQ(on_construct.value, 2); ASSERT_EQ(on_destroy.value, 0); @@ -55,32 +57,32 @@ TEST(SighStorageMixin, GenericType) { ASSERT_EQ(pool.get(entities[0u]), 0); ASSERT_EQ(pool.get(entities[1u]), 0); - base.erase(entities[0u], ®istry); - pool.erase(entities[1u], ®istry); + base.erase(entities[0u]); + pool.erase(entities[1u]); ASSERT_EQ(on_construct.value, 2); ASSERT_EQ(on_destroy.value, 2); ASSERT_TRUE(pool.empty()); - base.insert(std::begin(entities), std::end(entities), ®istry); + base.insert(std::begin(entities), std::end(entities)); ASSERT_EQ(pool.get(entities[0u]), 0); ASSERT_EQ(pool.get(entities[1u]), 0); ASSERT_FALSE(pool.empty()); - base.erase(entities[1u], ®istry); + base.erase(entities[1u]); ASSERT_EQ(on_construct.value, 4); ASSERT_EQ(on_destroy.value, 3); ASSERT_FALSE(pool.empty()); - base.erase(entities[0u], ®istry); + base.erase(entities[0u]); ASSERT_EQ(on_construct.value, 4); ASSERT_EQ(on_destroy.value, 4); ASSERT_TRUE(pool.empty()); - pool.insert(registry, std::begin(entities), std::end(entities), 3); + pool.insert(std::begin(entities), std::end(entities), 3); ASSERT_EQ(on_construct.value, 6); ASSERT_EQ(on_destroy.value, 4); @@ -89,7 +91,7 @@ TEST(SighStorageMixin, GenericType) { ASSERT_EQ(pool.get(entities[0u]), 3); ASSERT_EQ(pool.get(entities[1u]), 3); - pool.erase(std::begin(entities), std::end(entities), ®istry); + pool.erase(std::begin(entities), std::end(entities)); ASSERT_EQ(on_construct.value, 6); ASSERT_EQ(on_destroy.value, 6); @@ -102,14 +104,16 @@ TEST(SighStorageMixin, EmptyType) { entt::entity entities[2u]{entt::entity{3}, entt::entity{42}}; entt::registry registry{}; + pool.context(entt::forward_as_any(registry)); + counter on_construct{}; counter on_destroy{}; pool.on_construct().connect<&listener>(on_construct); pool.on_destroy().connect<&listener>(on_destroy); - base.emplace(entities[0u], ®istry); - pool.emplace(registry, entities[1u]); + base.emplace(entities[0u]); + pool.emplace(entities[1u]); ASSERT_EQ(on_construct.value, 2); ASSERT_EQ(on_destroy.value, 0); @@ -118,32 +122,32 @@ TEST(SighStorageMixin, EmptyType) { ASSERT_TRUE(pool.contains(entities[0u])); ASSERT_TRUE(pool.contains(entities[1u])); - base.erase(entities[0u], ®istry); - pool.erase(entities[1u], ®istry); + base.erase(entities[0u]); + pool.erase(entities[1u]); ASSERT_EQ(on_construct.value, 2); ASSERT_EQ(on_destroy.value, 2); ASSERT_TRUE(pool.empty()); - base.insert(std::begin(entities), std::end(entities), ®istry); + base.insert(std::begin(entities), std::end(entities)); ASSERT_TRUE(pool.contains(entities[0u])); ASSERT_TRUE(pool.contains(entities[1u])); ASSERT_FALSE(pool.empty()); - base.erase(entities[1u], ®istry); + base.erase(entities[1u]); ASSERT_EQ(on_construct.value, 4); ASSERT_EQ(on_destroy.value, 3); ASSERT_FALSE(pool.empty()); - base.erase(entities[0u], ®istry); + base.erase(entities[0u]); ASSERT_EQ(on_construct.value, 4); ASSERT_EQ(on_destroy.value, 4); ASSERT_TRUE(pool.empty()); - pool.insert(registry, std::begin(entities), std::end(entities)); + pool.insert(std::begin(entities), std::end(entities)); ASSERT_EQ(on_construct.value, 6); ASSERT_EQ(on_destroy.value, 4); @@ -152,7 +156,7 @@ TEST(SighStorageMixin, EmptyType) { ASSERT_TRUE(pool.contains(entities[0u])); ASSERT_TRUE(pool.contains(entities[1u])); - pool.erase(std::begin(entities), std::end(entities), ®istry); + pool.erase(std::begin(entities), std::end(entities)); ASSERT_EQ(on_construct.value, 6); ASSERT_EQ(on_destroy.value, 6); @@ -165,15 +169,17 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) { entt::entity entities[2u]{entt::entity{3}, entt::entity{42}}; entt::registry registry{}; + pool.context(entt::forward_as_any(registry)); + counter on_construct{}; counter on_destroy{}; pool.on_construct().connect<&listener>(on_construct); pool.on_destroy().connect<&listener>(on_destroy); - ASSERT_DEATH(base.emplace(entities[0u], ®istry), ""); + ASSERT_DEATH(base.emplace(entities[0u]), ""); - pool.emplace(registry, entities[1u], 3); + pool.emplace(entities[1u], 3); ASSERT_EQ(on_construct.value, 1); ASSERT_EQ(on_destroy.value, 0); @@ -182,19 +188,19 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) { ASSERT_FALSE(pool.contains(entities[0u])); ASSERT_EQ(pool.get(entities[1u]).value, 3); - base.erase(entities[1u], ®istry); + base.erase(entities[1u]); ASSERT_EQ(on_construct.value, 1); ASSERT_EQ(on_destroy.value, 1); ASSERT_TRUE(pool.empty()); - ASSERT_DEATH(base.insert(std::begin(entities), std::end(entities), ®istry), ""); + ASSERT_DEATH(base.insert(std::begin(entities), std::end(entities)), ""); ASSERT_FALSE(pool.contains(entities[0u])); ASSERT_FALSE(pool.contains(entities[1u])); ASSERT_TRUE(pool.empty()); - pool.insert(registry, std::begin(entities), std::end(entities), 3); + pool.insert(std::begin(entities), std::end(entities), 3); ASSERT_EQ(on_construct.value, 3); ASSERT_EQ(on_destroy.value, 1); @@ -203,7 +209,7 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) { ASSERT_EQ(pool.get(entities[0u]).value, 3); ASSERT_EQ(pool.get(entities[1u]).value, 3); - pool.erase(std::begin(entities), std::end(entities), ®istry); + pool.erase(std::begin(entities), std::end(entities)); ASSERT_EQ(on_construct.value, 3); ASSERT_EQ(on_destroy.value, 3); diff --git a/test/entt/entity/sparse_set.cpp b/test/entt/entity/sparse_set.cpp index 3aba93bce..df680304f 100644 --- a/test/entt/entity/sparse_set.cpp +++ b/test/entt/entity/sparse_set.cpp @@ -75,6 +75,8 @@ TEST(SparseSet, Functionalities) { ASSERT_EQ(set.begin(), set.end()); ASSERT_FALSE(set.contains(entt::entity{0})); ASSERT_FALSE(set.contains(entt::entity{42})); + + ASSERT_NO_THROW(set.context(entt::any{})); } TEST(SparseSet, Contains) { @@ -1169,35 +1171,6 @@ TEST(SparseSet, CanModifyDuringIteration) { [[maybe_unused]] const auto entity = *it; } -TEST(SparseSet, UserData) { - entt::sparse_set set; - int value = 42; - - ASSERT_EQ(set.user_data(), nullptr); - - set.user_data(&value); - entt::sparse_set other{std::move(set)}; - - ASSERT_EQ(std::as_const(set).user_data(), nullptr); - ASSERT_EQ(other.user_data(), &value); - - std::swap(set, other); - - ASSERT_EQ(set.user_data(), &value); - ASSERT_EQ(std::as_const(other).user_data(), nullptr); - - other = std::move(set); - - ASSERT_EQ(set.user_data(), nullptr); - ASSERT_EQ(other.user_data(), &value); - - entt::sparse_set last{std::move(other), std::allocator{}}; - - ASSERT_EQ(set.user_data(), nullptr); - ASSERT_EQ(other.user_data(), nullptr); - ASSERT_EQ(last.user_data(), &value); -} - TEST(SparseSet, CustomAllocator) { test::throwing_allocator allocator{}; entt::basic_sparse_set> set{allocator}; diff --git a/test/entt/entity/view.cpp b/test/entt/entity/view.cpp index cee5ab5de..6169fd0e3 100644 --- a/test/entt/entity/view.cpp +++ b/test/entt/entity/view.cpp @@ -1213,9 +1213,9 @@ TEST(MultiComponentView, SameComponentTypes) { const entt::entity e0{42u}; const entt::entity e1{3u}; - storage.emplace(registry, e0, 7); - other.emplace(registry, e0, 9); - other.emplace(registry, e1, 1); + storage.emplace(e0, 7); + other.emplace(e0, 9); + other.emplace(e1, 1); ASSERT_TRUE(view.contains(e0)); ASSERT_FALSE(view.contains(e1)); diff --git a/test/example/signal_less.cpp b/test/example/signal_less.cpp index d6c474b99..5964b2dd1 100644 --- a/test/example/signal_less.cpp +++ b/test/example/signal_less.cpp @@ -7,7 +7,7 @@ template struct entt::storage_traits { // no signal regardless of component type ... - using storage_type = storage_adapter_mixin>; + using storage_type = basic_storage; }; template