poly_storage.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. #include <cstddef>
  2. #include <gtest/gtest.h>
  3. #include <entt/core/utility.hpp>
  4. #include <entt/entity/poly_storage.hpp>
  5. #include <entt/entity/registry.hpp>
  6. template<typename... Type>
  7. entt::type_list<Type...> as_type_list(const entt::type_list<Type...> &);
  8. template<typename Entity>
  9. struct PolyStorage: entt::type_list_cat_t<
  10. decltype(as_type_list(std::declval<entt::Storage<Entity>>())),
  11. entt::type_list<
  12. void(entt::basic_registry<Entity> &, const Entity, const void *),
  13. const void *(const Entity) const,
  14. void(entt::basic_registry<Entity> &, entt::basic_registry<Entity> &)
  15. >
  16. > {
  17. using entity_type = Entity;
  18. using size_type = std::size_t;
  19. template<typename Base>
  20. struct type: entt::Storage<Entity>::template type<Base> {
  21. static constexpr auto base = std::tuple_size_v<typename entt::poly_vtable<entt::Storage<Entity>>::type>;
  22. void emplace(entt::basic_registry<entity_type> &owner, const entity_type entity, const void *instance) {
  23. entt::poly_call<base + 0>(*this, owner, entity, instance);
  24. }
  25. const void * get(const entity_type entity) const {
  26. return entt::poly_call<base + 1>(*this, entity);
  27. }
  28. void copy(entt::basic_registry<Entity> &owner, entt::basic_registry<Entity> &other) {
  29. entt::poly_call<base + 2>(*this, owner, other);
  30. }
  31. };
  32. template<typename Type>
  33. struct members {
  34. static void emplace(Type &self, entt::basic_registry<entity_type> &owner, const entity_type entity, const void *instance) {
  35. self.emplace(owner, entity, *static_cast<const typename Type::value_type *>(instance));
  36. }
  37. static const typename Type::value_type * get(const Type &self, const entity_type entity) {
  38. return &self.get(entity);
  39. }
  40. static void copy(Type &self, entt::basic_registry<entity_type> &owner, entt::basic_registry<entity_type> &other) {
  41. other.template insert<typename Type::value_type>(self.data(), self.data() + self.size(), self.raw(), self.raw() + self.size());
  42. }
  43. };
  44. template<typename Type>
  45. using impl = entt::value_list_cat_t<
  46. typename entt::Storage<Entity>::template impl<Type>,
  47. entt::value_list<
  48. &members<Type>::emplace,
  49. &members<Type>::get,
  50. &members<Type>::copy
  51. >
  52. >;
  53. };
  54. template<typename Entity>
  55. struct entt::poly_storage_traits<Entity> {
  56. using storage_type = entt::poly<PolyStorage<Entity>>;
  57. };
  58. TEST(PolyStorage, CopyEntity) {
  59. entt::registry registry;
  60. const auto entity = registry.create();
  61. const auto other = registry.create();
  62. registry.emplace<int>(entity, 42);
  63. registry.emplace<char>(entity, 'c');
  64. ASSERT_TRUE((registry.all_of<int, char>(entity)));
  65. ASSERT_FALSE((registry.any_of<int, char>(other)));
  66. registry.visit(entity, [&](const auto info) {
  67. auto storage = registry.storage(info);
  68. storage->emplace(registry, other, storage->get(entity));
  69. });
  70. ASSERT_TRUE((registry.all_of<int, char>(entity)));
  71. ASSERT_TRUE((registry.all_of<int, char>(other)));
  72. ASSERT_EQ(registry.get<int>(entity), registry.get<int>(other));
  73. ASSERT_EQ(registry.get<char>(entity), registry.get<char>(other));
  74. }
  75. TEST(PolyStorage, CopyRegistry) {
  76. entt::registry registry;
  77. entt::registry other;
  78. entt::entity entities[10u];
  79. registry.create(std::begin(entities), std::end(entities));
  80. registry.insert<int>(std::begin(entities), std::end(entities), 42);
  81. registry.insert<char>(std::begin(entities), std::end(entities), 'c');
  82. ASSERT_EQ(registry.size(), 10u);
  83. ASSERT_EQ(other.size(), 0u);
  84. other.assign(registry.data(), registry.data() + registry.size(), registry.destroyed());
  85. registry.visit([&](const auto info) { registry.storage(info)->copy(registry, other); });
  86. ASSERT_EQ(registry.size(), other.size());
  87. ASSERT_EQ((registry.view<int, char>().size_hint()), (other.view<int, char>().size_hint()));
  88. ASSERT_NE((other.view<int, char>().size_hint()), 0u);
  89. for(const auto entity: registry.view<int, char>()) {
  90. ASSERT_EQ((registry.get<int, char>(entity)), (other.get<int, char>(entity)));
  91. }
  92. }
  93. TEST(PolyStorage, Constness) {
  94. entt::registry registry;
  95. const auto &cregistry = registry;
  96. entt::entity entity[1];
  97. entity[0] = registry.create();
  98. registry.emplace<int>(entity[0], 42);
  99. auto cstorage = cregistry.storage(entt::type_id<int>());
  100. ASSERT_DEATH(cstorage->remove(registry, std::begin(entity), std::end(entity)), ".*");
  101. ASSERT_TRUE(registry.all_of<int>(entity[0]));
  102. auto storage = registry.storage(entt::type_id<int>());
  103. storage->remove(registry, std::begin(entity), std::end(entity));
  104. ASSERT_FALSE(registry.all_of<int>(entity[0]));
  105. }