From 4dc3f650e87d8f6a9c224e7456caba7b217ee77b Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Thu, 28 Mar 2024 10:49:18 +0100 Subject: [PATCH] snapshot: full support to stable types - close #1118 --- src/entt/entity/snapshot.hpp | 11 ++++++ test/entt/entity/snapshot.cpp | 73 ++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 10 deletions(-) diff --git a/src/entt/entity/snapshot.hpp b/src/entt/entity/snapshot.hpp index e9cc0fa63..8b5c0b624 100644 --- a/src/entt/entity/snapshot.hpp +++ b/src/entt/entity/snapshot.hpp @@ -86,6 +86,17 @@ public: for(auto first = storage->data(), last = first + storage->size(); first != last; ++first) { archive(*first); } + } else if constexpr(component_traits::in_place_delete) { + using common_type = typename registry_type::common_type; + + for(auto it = storage->common_type::rbegin(), last = storage->common_type::rend(); it != last; ++it) { + if(const auto entt = *it; entt == tombstone) { + archive(static_cast(null)); + } else { + archive(entt); + std::apply([&archive](auto &&...args) { (archive(std::forward(args)), ...); }, storage->get_as_tuple(entt)); + } + } } else { for(auto elem: storage->reach()) { std::apply([&archive](auto &&...args) { (archive(std::forward(args)), ...); }, elem); diff --git a/test/entt/entity/snapshot.cpp b/test/entt/entity/snapshot.cpp index cd14578f2..a4ce40f50 100644 --- a/test/entt/entity/snapshot.cpp +++ b/test/entt/entity/snapshot.cpp @@ -11,6 +11,7 @@ #include #include "../common/config.h" #include "../common/empty.h" +#include "../common/pointer_stable.h" struct shadow { entt::entity target{entt::null}; @@ -88,12 +89,13 @@ TEST(BasicSnapshot, GetType) { entt::registry registry; const entt::basic_snapshot snapshot{registry}; const auto &storage = registry.storage(); + constexpr auto number_of_entities = 3u; - entt::entity entity[3u]; // NOLINT - const int values[3u]{1, 2, 3}; // NOLINT + std::array entity{}; + const std::array value{1, 2, 3}; registry.create(std::begin(entity), std::end(entity)); - registry.insert(std::begin(entity), std::end(entity), std::begin(values)); + registry.insert(std::begin(entity), std::end(entity), std::begin(value)); registry.destroy(entity[1u]); std::vector data{}; @@ -118,13 +120,63 @@ TEST(BasicSnapshot, GetType) { ASSERT_EQ(entt::any_cast(data[1u]), entity[0u]); ASSERT_NE(entt::any_cast(&data[2u]), nullptr); - ASSERT_EQ(entt::any_cast(data[2u]), values[0u]); + ASSERT_EQ(entt::any_cast(data[2u]), value[0u]); ASSERT_NE(entt::any_cast(&data[3u]), nullptr); ASSERT_EQ(entt::any_cast(data[3u]), entity[2u]); ASSERT_NE(entt::any_cast(&data[4u]), nullptr); - ASSERT_EQ(entt::any_cast(data[4u]), values[2u]); + ASSERT_EQ(entt::any_cast(data[4u]), value[2u]); +} + +TEST(BasicSnapshot, GetPointerStableType) { + using namespace entt::literals; + using traits_type = entt::entt_traits; + + entt::registry registry; + const entt::basic_snapshot snapshot{registry}; + const auto &storage = registry.storage(); + constexpr auto number_of_entities = 3u; + + std::array entity{}; + const std::array value{1, 2, 3}; + + registry.create(entity.begin(), entity.end()); + registry.insert(entity.begin(), entity.end(), value.begin()); + registry.destroy(entity[1u]); + + std::vector data{}; + auto archive = [&data](auto &&elem) { data.emplace_back(std::forward(elem)); }; + + snapshot.get(archive, "other"_hs); + + ASSERT_EQ(data.size(), 1u); + + ASSERT_NE(entt::any_cast(&data[0u]), nullptr); + ASSERT_EQ(entt::any_cast(data[0u]), 0u); + + data.clear(); + snapshot.get(archive); + + ASSERT_EQ(data.size(), 6u); + + ASSERT_NE(entt::any_cast(&data[0u]), nullptr); + ASSERT_EQ(entt::any_cast(data[0u]), storage.size()); + + ASSERT_NE(entt::any_cast(&data[1u]), nullptr); + ASSERT_EQ(entt::any_cast(data[1u]), entity[0u]); + + ASSERT_NE(entt::any_cast(&data[2u]), nullptr); + ASSERT_EQ(entt::any_cast(data[2u]), value[0u]); + + ASSERT_NE(entt::any_cast(&data[3u]), nullptr); + ASSERT_EQ(entt::any_cast(data[3u]), static_cast(entt::null)); + + ASSERT_NE(entt::any_cast(&data[4u]), nullptr); + ASSERT_EQ(entt::any_cast(data[4u]), entity[2u]); + + ASSERT_NE(entt::any_cast(&data[5u]), nullptr); + ASSERT_EQ(entt::any_cast(data[5u]), value[2u]); } TEST(BasicSnapshot, GetEmptyType) { @@ -172,12 +224,13 @@ TEST(BasicSnapshot, GetTypeSparse) { entt::registry registry; const entt::basic_snapshot snapshot{registry}; + constexpr auto number_of_entities = 3u; - entt::entity entity[3u]; // NOLINT - const int values[3u]{1, 2, 3}; // NOLINT + std::array entity{}; + const std::array value{1, 2, 3}; registry.create(std::begin(entity), std::end(entity)); - registry.insert(std::begin(entity), std::end(entity), std::begin(values)); + registry.insert(std::begin(entity), std::end(entity), std::begin(value)); registry.destroy(entity[1u]); std::vector data{}; @@ -202,7 +255,7 @@ TEST(BasicSnapshot, GetTypeSparse) { ASSERT_EQ(entt::any_cast(data[1u]), entity[0u]); ASSERT_NE(entt::any_cast(&data[2u]), nullptr); - ASSERT_EQ(entt::any_cast(data[2u]), values[0u]); + ASSERT_EQ(entt::any_cast(data[2u]), value[0u]); ASSERT_NE(entt::any_cast(&data[3u]), nullptr); ASSERT_EQ(entt::any_cast(data[3u]), static_cast(entt::null)); @@ -211,7 +264,7 @@ TEST(BasicSnapshot, GetTypeSparse) { ASSERT_EQ(entt::any_cast(data[4u]), entity[2u]); ASSERT_NE(entt::any_cast(&data[5u]), nullptr); - ASSERT_EQ(entt::any_cast(data[5u]), values[2u]); + ASSERT_EQ(entt::any_cast(data[5u]), value[2u]); } TEST(BasicSnapshotLoader, Constructors) {