Преглед изворни кода

snapshot:
* single element only archive functions required
* avoid iterating elements more than once

Michele Caini пре 2 година
родитељ
комит
0b6ad03150
2 измењених фајлова са 39 додато и 37 уклоњено
  1. 29 27
      src/entt/entity/snapshot.hpp
  2. 10 10
      test/entt/entity/snapshot.cpp

+ 29 - 27
src/entt/entity/snapshot.hpp

@@ -83,7 +83,7 @@ public:
             archive(static_cast<typename traits_type::entity_type>(storage->size()));
 
             for(auto elem: storage->reach()) {
-                std::apply(archive, elem);
+                std::apply([&archive](auto &&...args) { (archive(std::forward<decltype(args)>(args)), ...); }, elem);
             }
         } else {
             archive(typename traits_type::entity_type{});
@@ -122,18 +122,14 @@ public:
      */
     template<typename Component, typename Archive, typename It>
     const basic_snapshot &component(Archive &archive, It first, It last) const {
-        const auto view = reg->template view<Component>();
-        std::size_t size{};
+        archive(static_cast<typename traits_type::entity_type>(std::distance(first, last)));
 
-        for(auto it = first; it != last; ++it) {
-            size += view.contains(*it);
-        }
-
-        archive(static_cast<typename traits_type::entity_type>(size));
-
-        for(auto it = first; it != last; ++it) {
-            if(view.contains(*it)) {
-                std::apply(archive, std::tuple_cat(std::make_tuple(*it), view.get(*it)));
+        for(const auto view = reg->template view<Component>(); first != last; ++first) {
+            if(const auto entt = *first; view.contains(entt)) {
+                archive(entt);
+                std::apply([&archive](auto &&...args) { (archive(std::forward<decltype(args)>(args)), ...); }, view.get(entt));
+            } else {
+                archive(static_cast<entity_type>(null));
             }
         }
 
@@ -252,19 +248,22 @@ public:
 
         if constexpr(Registry::template storage_for_type<Component>::traits_type::page_size == 0u) {
             while(length--) {
-                archive(entt);
-                const auto entity = storage.contains(entt) ? entt : storage.emplace(entt);
-                ENTT_ASSERT(entity == entt, "Entity not available for use");
-                elem.emplace(entity);
+                if(archive(entt); entt != null) {
+                    const auto entity = storage.contains(entt) ? entt : storage.emplace(entt);
+                    ENTT_ASSERT(entity == entt, "Entity not available for use");
+                    elem.emplace(entity);
+                }
             }
         } else {
             Component instance;
 
             while(length--) {
-                archive(entt, instance);
-                const auto entity = storage.contains(entt) ? entt : storage.emplace(entt);
-                ENTT_ASSERT(entity == entt, "Entity not available for use");
-                elem.emplace(entity, std::move(instance));
+                if(archive(entt); entt != null) {
+                    archive(instance);
+                    const auto entity = storage.contains(entt) ? entt : storage.emplace(entt);
+                    ENTT_ASSERT(entity == entt, "Entity not available for use");
+                    elem.emplace(entity, std::move(instance));
+                }
             }
         }
 
@@ -428,18 +427,21 @@ class basic_continuous_loader {
 
         if constexpr(Registry::template storage_for_type<Component>::traits_type::page_size == 0u) {
             while(length--) {
-                archive(entt);
-                restore(entt);
-                storage.emplace(map(entt));
+                if(archive(entt); entt != null) {
+                    restore(entt);
+                    storage.emplace(map(entt));
+                }
             }
         } else {
             Component instance;
 
             while(length--) {
-                archive(entt, instance);
-                (update(instance, member), ...);
-                restore(entt);
-                storage.emplace(map(entt), std::move(instance));
+                if(archive(entt); entt != null) {
+                    archive(instance);
+                    (update(instance, member), ...);
+                    restore(entt);
+                    storage.emplace(map(entt), std::move(instance));
+                }
             }
         }
     }

+ 10 - 10
test/entt/entity/snapshot.cpp

@@ -15,13 +15,13 @@ struct output_archive {
     output_archive(Storage &instance)
         : storage{instance} {}
 
-    template<typename... Value>
-    void operator()(const Value &...value) {
-        (std::get<std::queue<Value>>(storage).push(value), ...);
+    template<typename Value>
+    void operator()(const Value &value) {
+        std::get<std::queue<Value>>(storage).push(value);
     }
 
-    void operator()(const entt::entity &entity, const std::unique_ptr<int> &instance) {
-        (*this)(entity, *instance);
+    void operator()(const std::unique_ptr<int> &instance) {
+        (*this)(*instance);
     }
 
 private:
@@ -33,20 +33,20 @@ struct input_archive {
     input_archive(Storage &instance)
         : storage{instance} {}
 
-    template<typename... Value>
-    void operator()(Value &...value) {
+    template<typename Value>
+    void operator()(Value &value) {
         auto assign = [this](auto &val) {
             auto &queue = std::get<std::queue<std::decay_t<decltype(val)>>>(storage);
             val = queue.front();
             queue.pop();
         };
 
-        (assign(value), ...);
+        assign(value);
     }
 
-    void operator()(entt::entity &entity, std::unique_ptr<int> &instance) {
+    void operator()(std::unique_ptr<int> &instance) {
         instance = std::make_unique<int>();
-        (*this)(entity, *instance);
+        (*this)(*instance);
     }
 
 private: