Quellcode durchsuchen

registry: added weak ::storage for opaque cross registry operations

Michele Caini vor 4 Jahren
Ursprung
Commit
e1b3f2b95a
4 geänderte Dateien mit 60 neuen und 6 gelöschten Zeilen
  1. 0 1
      TODO
  2. 22 3
      src/entt/entity/registry.hpp
  3. 8 2
      test/entt/entity/registry.cpp
  4. 30 0
      test/example/entity_copy.cpp

+ 0 - 1
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<E>

+ 22 - 3
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<typename Component>
@@ -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<typename Component>
@@ -361,6 +361,25 @@ public:
         return assure<Component>(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<base_type *>(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.

+ 8 - 2
test/entt/entity/registry.cpp

@@ -1881,8 +1881,14 @@ TEST(Registry, RuntimePools) {
     static_assert(std::is_same_v<decltype(registry.storage<empty_type>()), typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
     static_assert(std::is_same_v<decltype(std::as_const(registry).storage<empty_type>()), const typename entt::storage_traits<entt::entity, empty_type>::storage_type &>);
 
-    ASSERT_EQ(&storage, &registry.storage<empty_type>("other"_hs));
-    ASSERT_EQ(&registry.storage<empty_type>(), &registry.storage<empty_type>());
+    static_assert(std::is_same_v<decltype(registry.storage("other"_hs)), typename entt::storage_traits<entt::entity, empty_type>::storage_type::base_type *>);
+    static_assert(std::is_same_v<decltype(std::as_const(registry).storage("other"_hs)), const typename entt::storage_traits<entt::entity, empty_type>::storage_type::base_type *>);
+
+    ASSERT_EQ(registry.storage("other"_hs), &storage);
+    ASSERT_EQ(std::as_const(registry).storage("rehto"_hs), nullptr);
+
+    ASSERT_EQ(&registry.storage<empty_type>("other"_hs), &storage);
+    ASSERT_NE(&registry.storage<empty_type>(), &storage);
 
     ASSERT_FALSE(registry.any_of<empty_type>(entity));
     ASSERT_FALSE(storage.contains(entity));

+ 30 - 0
test/example/entity_copy.cpp

@@ -1,6 +1,9 @@
 #include <gtest/gtest.h>
+#include <entt/core/utility.hpp>
 #include <entt/entity/registry.hpp>
 
+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<int>(dst), 42);
     ASSERT_EQ(registry.get<char>(dst), 'c');
 }
+
+TEST(Example, DifferentRegistryTypes) {
+    using namespace entt::literals;
+
+    entt::basic_registry<entt::entity> registry{};
+    entt::basic_registry<my_entity> other{};
+
+    static_cast<void>(registry.storage<double>());
+    static_cast<void>(other.storage<int>());
+
+    const auto src = registry.create();
+    const auto dst = other.create();
+
+    registry.emplace<int>(src, 42);
+    registry.emplace<char>(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<int, char>(src)));
+    ASSERT_FALSE(other.all_of<char>(dst));
+    ASSERT_TRUE(other.all_of<int>(dst));
+    ASSERT_EQ(other.get<int>(dst), 42);
+}