🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
5.5 KiB

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