snapshot.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #include <gtest/gtest.h>
  2. #include <sstream>
  3. #include <vector>
  4. #include <cereal/archives/json.hpp>
  5. #include <entt/entity/registry.hpp>
  6. struct Position {
  7. float x;
  8. float y;
  9. };
  10. struct Timer {
  11. int duration;
  12. int elapsed{0};
  13. };
  14. struct Relationship {
  15. entt::DefaultRegistry::entity_type parent;
  16. };
  17. template<typename Archive>
  18. void serialize(Archive &archive, Position &position) {
  19. archive(position.x, position.y);
  20. }
  21. template<typename Archive>
  22. void serialize(Archive &archive, Timer &timer) {
  23. archive(timer.duration);
  24. }
  25. template<typename Archive>
  26. void serialize(Archive &archive, Relationship &relationship) {
  27. archive(relationship.parent);
  28. }
  29. TEST(Snapshot, Full) {
  30. std::stringstream storage;
  31. entt::DefaultRegistry source;
  32. entt::DefaultRegistry destination;
  33. auto e0 = source.create();
  34. source.assign<Position>(e0, 16.f, 16.f);
  35. source.destroy(source.create());
  36. auto e1 = source.create();
  37. source.assign<Position>(e1, .8f, .0f);
  38. source.assign<Relationship>(e1, e0);
  39. auto e2 = source.create();
  40. auto e3 = source.create();
  41. source.assign<Timer>(e3, 1000, 100);
  42. source.destroy(e2);
  43. auto v2 = source.current(e2);
  44. {
  45. // output finishes flushing its contents when it goes out of scope
  46. cereal::JSONOutputArchive output{storage};
  47. source.snapshot().entities(output).destroyed(output)
  48. .component<Position, Timer, Relationship>(output);
  49. }
  50. cereal::JSONInputArchive input{storage};
  51. destination.restore().entities(input).destroyed(input)
  52. .component<Position, Timer, Relationship>(input);
  53. ASSERT_TRUE(destination.valid(e0));
  54. ASSERT_TRUE(destination.has<Position>(e0));
  55. ASSERT_EQ(destination.get<Position>(e0).x, 16.f);
  56. ASSERT_EQ(destination.get<Position>(e0).y, 16.f);
  57. ASSERT_TRUE(destination.valid(e1));
  58. ASSERT_TRUE(destination.has<Position>(e1));
  59. ASSERT_EQ(destination.get<Position>(e1).x, .8f);
  60. ASSERT_EQ(destination.get<Position>(e1).y, .0f);
  61. ASSERT_TRUE(destination.has<Relationship>(e1));
  62. ASSERT_EQ(destination.get<Relationship>(e1).parent, e0);
  63. ASSERT_FALSE(destination.valid(e2));
  64. ASSERT_EQ(destination.current(e2), v2);
  65. ASSERT_TRUE(destination.valid(e3));
  66. ASSERT_TRUE(destination.has<Timer>(e3));
  67. ASSERT_EQ(destination.get<Timer>(e3).duration, 1000);
  68. ASSERT_EQ(destination.get<Timer>(e3).elapsed, 0);
  69. }
  70. TEST(Snapshot, Continuous) {
  71. std::stringstream storage;
  72. entt::DefaultRegistry source;
  73. entt::DefaultRegistry destination;
  74. std::vector<entt::DefaultRegistry::entity_type> entities;
  75. for(auto i = 0; i < 10; ++i) {
  76. entities.push_back(source.create());
  77. }
  78. for(auto entity: entities) {
  79. source.destroy(entity);
  80. }
  81. auto e0 = source.create();
  82. source.assign<Position>(e0, 0.f, 0.f);
  83. source.assign<Relationship>(e0, e0);
  84. auto e1 = source.create();
  85. source.assign<Position>(e1, 1.f, 1.f);
  86. source.assign<Relationship>(e1, e0);
  87. auto e2 = source.create();
  88. source.assign<Position>(e2, .2f, .2f);
  89. source.assign<Relationship>(e2, e0);
  90. auto e3 = source.create();
  91. source.assign<Timer>(e3, 1000, 1000);
  92. source.assign<Relationship>(e3, e2);
  93. {
  94. // output finishes flushing its contents when it goes out of scope
  95. cereal::JSONOutputArchive output{storage};
  96. source.snapshot().entities(output).component<Position, Relationship, Timer>(output);
  97. }
  98. cereal::JSONInputArchive input{storage};
  99. entt::ContinuousLoader<entt::DefaultRegistry::entity_type> loader{destination};
  100. loader.entities(input)
  101. .component<Position>(input)
  102. .component<Relationship>(input, &Relationship::parent)
  103. .component<Timer>(input);
  104. ASSERT_FALSE(destination.valid(e0));
  105. ASSERT_TRUE(loader.has(e0));
  106. auto l0 = loader.map(e0);
  107. ASSERT_TRUE(destination.valid(l0));
  108. ASSERT_TRUE(destination.has<Position>(l0));
  109. ASSERT_EQ(destination.get<Position>(l0).x, 0.f);
  110. ASSERT_EQ(destination.get<Position>(l0).y, 0.f);
  111. ASSERT_TRUE(destination.has<Relationship>(l0));
  112. ASSERT_EQ(destination.get<Relationship>(l0).parent, l0);
  113. ASSERT_FALSE(destination.valid(e1));
  114. ASSERT_TRUE(loader.has(e1));
  115. auto l1 = loader.map(e1);
  116. ASSERT_TRUE(destination.valid(l1));
  117. ASSERT_TRUE(destination.has<Position>(l1));
  118. ASSERT_EQ(destination.get<Position>(l1).x, 1.f);
  119. ASSERT_EQ(destination.get<Position>(l1).y, 1.f);
  120. ASSERT_TRUE(destination.has<Relationship>(l1));
  121. ASSERT_EQ(destination.get<Relationship>(l1).parent, l0);
  122. ASSERT_FALSE(destination.valid(e2));
  123. ASSERT_TRUE(loader.has(e2));
  124. auto l2 = loader.map(e2);
  125. ASSERT_TRUE(destination.valid(l2));
  126. ASSERT_TRUE(destination.has<Position>(l2));
  127. ASSERT_EQ(destination.get<Position>(l2).x, .2f);
  128. ASSERT_EQ(destination.get<Position>(l2).y, .2f);
  129. ASSERT_TRUE(destination.has<Relationship>(l2));
  130. ASSERT_EQ(destination.get<Relationship>(l2).parent, l0);
  131. ASSERT_FALSE(destination.valid(e3));
  132. ASSERT_TRUE(loader.has(e3));
  133. auto l3 = loader.map(e3);
  134. ASSERT_TRUE(destination.valid(l3));
  135. ASSERT_TRUE(destination.has<Timer>(l3));
  136. ASSERT_EQ(destination.get<Timer>(l3).duration, 1000);
  137. ASSERT_EQ(destination.get<Timer>(l3).elapsed, 0);
  138. ASSERT_TRUE(destination.has<Relationship>(l3));
  139. ASSERT_EQ(destination.get<Relationship>(l3).parent, l2);
  140. }