From e1b3f2b95ac7e00254fd08627d81046f7d23cafc Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 22 Dec 2021 16:18:24 +0100 Subject: [PATCH] registry: added weak ::storage for opaque cross registry operations --- TODO | 1 - src/entt/entity/registry.hpp | 25 ++++++++++++++++++++++--- test/entt/entity/registry.cpp | 10 ++++++++-- test/example/entity_copy.cpp | 30 ++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index 733bbf279..3bde7090d 100644 --- a/TODO +++ b/TODO @@ -5,7 +5,6 @@ WIP: * add the possibility of disabling entities without deleting components thanks to the new full check -* add registry::storage id -> basic_sparse_set (no template arg), add example of use * fast-contains for sparse sets (low prio but nice-to-have) * 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 b4a0ce6f4..39cfb8ad1 100644 --- a/src/entt/entity/registry.hpp +++ b/src/entt/entity/registry.hpp @@ -337,7 +337,7 @@ public: /** * @brief Returns the storage for a given component type. * @tparam Component Type of component of which to return the storage. - * @param id Optional name used to map the storage for a given component. + * @param id Optional name used to map the storage within the registry. * @return The storage for the given component type. */ template @@ -346,14 +346,14 @@ public: } /** - * @copybrief storage + * @brief Returns the storage for a given component type. * * @warning * If a storage for the given component doesn't exist yet, a temporary * placeholder is returned instead. * * @tparam Component Type of component of which to return the storage. - * @param id Optional name used to map the storage for a given component. + * @param id Optional name used to map the storage within the registry. * @return The storage for the given component type. */ template @@ -361,6 +361,25 @@ public: return assure(id); } + /** + * @brief Returns the storage associated with a given name, if any. + * @param id Name used to map the storage within the registry. + * @return The requested storage if it exists, a null pointer otherwise. + */ + [[nodiscard]] base_type *storage(const id_type id) { + return const_cast(std::as_const(*this).storage(id)); + } + + /** + * @brief Returns the storage associated with a given name, if any. + * @param id Name used to map the storage within the registry. + * @return The requested storage if it exists, a null pointer otherwise. + */ + [[nodiscard]] const base_type *storage(const id_type id) const { + const auto it = pools.find(id); + return it == pools.end() ? nullptr : it->second.get(); + } + /** * @brief Returns the number of entities created so far. * @return Number of entities created so far. diff --git a/test/entt/entity/registry.cpp b/test/entt/entity/registry.cpp index 1c63724d6..04440c566 100644 --- a/test/entt/entity/registry.cpp +++ b/test/entt/entity/registry.cpp @@ -1881,8 +1881,14 @@ TEST(Registry, RuntimePools) { static_assert(std::is_same_v()), typename entt::storage_traits::storage_type &>); static_assert(std::is_same_v()), const typename entt::storage_traits::storage_type &>); - ASSERT_EQ(&storage, ®istry.storage("other"_hs)); - ASSERT_EQ(®istry.storage(), ®istry.storage()); + static_assert(std::is_same_v::storage_type::base_type *>); + static_assert(std::is_same_v::storage_type::base_type *>); + + ASSERT_EQ(registry.storage("other"_hs), &storage); + ASSERT_EQ(std::as_const(registry).storage("rehto"_hs), nullptr); + + ASSERT_EQ(®istry.storage("other"_hs), &storage); + ASSERT_NE(®istry.storage(), &storage); ASSERT_FALSE(registry.any_of(entity)); ASSERT_FALSE(storage.contains(entity)); diff --git a/test/example/entity_copy.cpp b/test/example/entity_copy.cpp index 09ca2735c..e6cab80f2 100644 --- a/test/example/entity_copy.cpp +++ b/test/example/entity_copy.cpp @@ -1,6 +1,9 @@ #include +#include #include +enum class my_entity : entt::id_type {}; + TEST(Example, EntityCopy) { using namespace entt::literals; @@ -36,3 +39,30 @@ TEST(Example, EntityCopy) { ASSERT_EQ(registry.get(dst), 42); ASSERT_EQ(registry.get(dst), 'c'); } + +TEST(Example, DifferentRegistryTypes) { + using namespace entt::literals; + + entt::basic_registry registry{}; + entt::basic_registry other{}; + + static_cast(registry.storage()); + static_cast(other.storage()); + + const auto src = registry.create(); + const auto dst = other.create(); + + registry.emplace(src, 42); + registry.emplace(src, 'c'); + + for(auto [id, storage]: registry.storage()) { + if(auto *pool = other.storage(id); pool && storage.contains(src)) { + pool->emplace(dst, storage.get(src)); + } + } + + ASSERT_TRUE((registry.all_of(src))); + ASSERT_FALSE(other.all_of(dst)); + ASSERT_TRUE(other.all_of(dst)); + ASSERT_EQ(other.get(dst), 42); +}