Kaynağa Gözat

snapshot: reintroduce support to storage listeners

Michele Caini 2 yıl önce
ebeveyn
işleme
c1f6b11f7d
2 değiştirilmiş dosya ile 67 ekleme ve 3 silme
  1. 8 3
      src/entt/entity/snapshot.hpp
  2. 59 0
      test/entt/entity/snapshot.cpp

+ 8 - 3
src/entt/entity/snapshot.hpp

@@ -259,7 +259,9 @@ public:
                     if constexpr(Registry::template storage_for_type<Type>::traits_type::page_size == 0u) {
                         storage.emplace(entity);
                     } else {
-                        archive(storage.emplace(entity));
+                        Type elem{};
+                        archive(elem);
+                        storage.emplace(entity, std::move(elem));
                     }
                 }
             }
@@ -466,7 +468,9 @@ public:
                     if constexpr(Registry::template storage_for_type<Type>::traits_type::page_size == 0u) {
                         storage.emplace(map(entt));
                     } else {
-                        archive(storage.emplace(map(entt)));
+                        Type elem{};
+                        archive(elem);
+                        storage.emplace(map(entt), std::move(elem));
                     }
                 }
             }
@@ -523,9 +527,10 @@ public:
                     if constexpr(std::remove_reference_t<decltype(storage)>::traits_type::page_size == 0u) {
                         storage.emplace(map(entt));
                     } else {
-                        auto &elem = storage.emplace(map(entt));
+                        typename std::remove_reference_t<decltype(storage)>::value_type elem{};
                         archive(elem);
                         (update(elem, member), ...);
+                        storage.emplace(map(entt), std::move(elem));
                     }
                 }
             }

+ 59 - 0
test/entt/entity/snapshot.cpp

@@ -11,11 +11,16 @@
 #include <entt/entity/entity.hpp>
 #include <entt/entity/registry.hpp>
 #include <entt/entity/snapshot.hpp>
+#include <entt/signal/sigh.hpp>
 
 struct empty {};
 
 struct shadow {
     entt::entity target{entt::null};
+
+    static void listener(entt::entity &elem, entt::registry &registry, const entt::entity entt) {
+        elem = registry.get<shadow>(entt).target;
+    }
 };
 
 TEST(BasicSnapshot, Constructors) {
@@ -417,6 +422,33 @@ TEST(BasicSnapshotLoader, GetTypeSparse) {
     ASSERT_EQ(storage.get(entities[1u]), values[1u]);
 }
 
+TEST(BasicSnapshotLoader, GetTypeWithListener) {
+    using traits_type = entt::entt_traits<entt::entity>;
+
+    entt::registry registry;
+    entt::basic_snapshot_loader loader{registry};
+    entt::entity check{entt::null};
+
+    std::vector<entt::any> data{};
+    auto archive = [&data, pos = 0u](auto &value) mutable { value = entt::any_cast<std::remove_reference_t<decltype(value)>>(data[pos++]); };
+    const auto entity{traits_type::construct(1u, 1u)};
+    const shadow value{entity};
+
+    ASSERT_FALSE(registry.valid(entity));
+    ASSERT_EQ(check, static_cast<entt::entity>(entt::null));
+
+    registry.on_construct<shadow>().connect<&shadow::listener>(check);
+
+    data.emplace_back(static_cast<typename traits_type::entity_type>(1u));
+    data.emplace_back(entity);
+    data.emplace_back(value);
+
+    loader.get<shadow>(archive);
+
+    ASSERT_TRUE(registry.valid(entity));
+    ASSERT_EQ(check, entity);
+}
+
 TEST(BasicSnapshotLoader, Orphans) {
     using namespace entt::literals;
     using traits_type = entt::entt_traits<entt::entity>;
@@ -823,6 +855,33 @@ TEST(BasicContinuousLoader, GetTypeSparse) {
     ASSERT_EQ(storage.get(loader.map(entities[1u])), values[1u]);
 }
 
+TEST(BasicContinuousLoader, GetTypeWithListener) {
+    using traits_type = entt::entt_traits<entt::entity>;
+
+    entt::registry registry;
+    entt::basic_continuous_loader loader{registry};
+    entt::entity check{entt::null};
+
+    std::vector<entt::any> data{};
+    auto archive = [&data, pos = 0u](auto &value) mutable { value = entt::any_cast<std::remove_reference_t<decltype(value)>>(data[pos++]); };
+    const auto entity{traits_type::construct(1u, 1u)};
+    const shadow value{entity};
+
+    ASSERT_FALSE(registry.valid(loader.map(entity)));
+    ASSERT_EQ(check, static_cast<entt::entity>(entt::null));
+
+    registry.on_construct<shadow>().connect<&shadow::listener>(check);
+
+    data.emplace_back(static_cast<typename traits_type::entity_type>(1u));
+    data.emplace_back(entity);
+    data.emplace_back(value);
+
+    loader.get<shadow>(archive);
+
+    ASSERT_TRUE(registry.valid(loader.map(entity)));
+    ASSERT_EQ(check, entity);
+}
+
 TEST(BasicContinuousLoader, Shrink) {
     entt::registry registry;
     entt::basic_continuous_loader loader{registry};