entity_copy.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <gtest/gtest.h>
  2. #include <entt/core/hashed_string.hpp>
  3. #include <entt/core/utility.hpp>
  4. #include <entt/entity/registry.hpp>
  5. #include <entt/entity/storage.hpp>
  6. #include <entt/meta/factory.hpp>
  7. #include <entt/meta/resolve.hpp>
  8. enum class my_entity : entt::id_type {};
  9. template<typename Type>
  10. struct meta_mixin: Type {
  11. using allocator_type = typename Type::allocator_type;
  12. using value_type = typename Type::value_type;
  13. explicit meta_mixin(const allocator_type &allocator)
  14. : Type{allocator} {
  15. using namespace entt::literals;
  16. entt::meta<value_type>()
  17. // cross registry, same type
  18. .func<entt::overload<entt::storage_for_t<value_type, entt::entity> &(const entt::id_type)>(&entt::basic_registry<entt::entity>::storage<value_type>), entt::as_ref_t>("storage"_hs)
  19. // cross registry, different types
  20. .func<entt::overload<entt::storage_for_t<value_type, my_entity> &(const entt::id_type)>(&entt::basic_registry<my_entity>::storage<value_type>), entt::as_ref_t>("storage"_hs);
  21. }
  22. };
  23. template<typename Type, typename Entity>
  24. struct entt::storage_type<Type, Entity> {
  25. using type = meta_mixin<basic_storage<Type, Entity>>;
  26. };
  27. template<typename Type>
  28. struct EntityCopy: testing::Test {
  29. using type = Type;
  30. };
  31. using EntityCopyTypes = ::testing::Types<entt::basic_registry<entt::entity>, entt::basic_registry<my_entity>>;
  32. TYPED_TEST_SUITE(EntityCopy, EntityCopyTypes, );
  33. TEST(EntityCopy, SameRegistry) {
  34. using namespace entt::literals;
  35. entt::registry registry{};
  36. auto &&custom = registry.storage<double>("custom"_hs);
  37. const auto src = registry.create();
  38. const auto dst = registry.create();
  39. custom.emplace(src, 1.);
  40. registry.emplace<int>(src, 42);
  41. registry.emplace<char>(src, 'c');
  42. ASSERT_EQ(registry.size(), 2u);
  43. ASSERT_TRUE(custom.contains(src));
  44. ASSERT_FALSE(custom.contains(dst));
  45. ASSERT_TRUE((registry.all_of<int, char>(src)));
  46. ASSERT_FALSE((registry.any_of<int, char>(dst)));
  47. for(auto it = ++registry.storage().begin(), last = registry.storage().end(); it != last; ++it) {
  48. // discard the custom storage because why not, this is just an example after all
  49. if(auto [id, storage] = *it; id != "custom"_hs && storage.contains(src)) {
  50. storage.push(dst, storage.value(src));
  51. }
  52. }
  53. ASSERT_EQ(registry.size(), 2u);
  54. ASSERT_TRUE(custom.contains(src));
  55. ASSERT_FALSE(custom.contains(dst));
  56. ASSERT_TRUE((registry.all_of<int, char>(src)));
  57. ASSERT_TRUE((registry.all_of<int, char>(dst)));
  58. ASSERT_EQ(registry.get<int>(dst), 42);
  59. ASSERT_EQ(registry.get<char>(dst), 'c');
  60. }
  61. TYPED_TEST(EntityCopy, CrossRegistry) {
  62. using namespace entt::literals;
  63. entt::basic_registry<entt::entity> src{};
  64. // other registry type, see typed test suite
  65. typename TestFixture::type dst{};
  66. const auto entity = src.create();
  67. const auto copy = dst.create();
  68. src.emplace<int>(entity, 42);
  69. src.emplace<char>(entity, 'c');
  70. ASSERT_EQ(src.size(), 1u);
  71. ASSERT_EQ(dst.size(), 1u);
  72. ASSERT_TRUE((src.all_of<int, char>(entity)));
  73. ASSERT_FALSE((dst.all_of<int, char>(copy)));
  74. for(auto it = ++src.storage().begin(), last = src.storage().end(); it != last; ++it) {
  75. if(auto [id, storage] = *it; storage.contains(entity)) {
  76. auto *other = dst.storage(id);
  77. if(!other) {
  78. using namespace entt::literals;
  79. entt::resolve(storage.type()).invoke("storage"_hs, {}, entt::forward_as_meta(dst), id);
  80. other = dst.storage(id);
  81. }
  82. other->push(copy, storage.value(entity));
  83. }
  84. }
  85. ASSERT_EQ(src.size(), 1u);
  86. ASSERT_EQ(dst.size(), 1u);
  87. ASSERT_TRUE((src.all_of<int, char>(entity)));
  88. ASSERT_TRUE((dst.all_of<int, char>(copy)));
  89. ASSERT_EQ(dst.get<int>(copy), 42);
  90. ASSERT_EQ(dst.get<char>(copy), 'c');
  91. }