handle.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. #include <type_traits>
  2. #include <utility>
  3. #include <gtest/gtest.h>
  4. #include <entt/entity/entity.hpp>
  5. #include <entt/entity/handle.hpp>
  6. #include <entt/entity/registry.hpp>
  7. TEST(BasicHandle, Assumptions) {
  8. static_assert(std::is_trivially_copyable_v<entt::handle>);
  9. static_assert(std::is_trivially_assignable_v<entt::handle, entt::handle>);
  10. static_assert(std::is_trivially_destructible_v<entt::handle>);
  11. static_assert(std::is_trivially_copyable_v<entt::const_handle>);
  12. static_assert(std::is_trivially_assignable_v<entt::const_handle, entt::const_handle>);
  13. static_assert(std::is_trivially_destructible_v<entt::const_handle>);
  14. }
  15. TEST(BasicHandle, DeductionGuide) {
  16. static_assert(std::is_same_v<decltype(entt::basic_handle{std::declval<entt::registry &>(), {}}), entt::basic_handle<entt::entity>>);
  17. static_assert(std::is_same_v<decltype(entt::basic_handle{std::declval<const entt::registry &>(), {}}), entt::basic_handle<const entt::entity>>);
  18. }
  19. TEST(BasicHandle, Construction) {
  20. entt::registry registry;
  21. const auto entity = registry.create();
  22. entt::handle handle{registry, entity};
  23. entt::const_handle chandle{std::as_const(registry), entity};
  24. ASSERT_FALSE(entt::null == handle.entity());
  25. ASSERT_EQ(entity, handle);
  26. ASSERT_TRUE(handle);
  27. ASSERT_FALSE(entt::null == chandle.entity());
  28. ASSERT_EQ(entity, chandle);
  29. ASSERT_TRUE(chandle);
  30. ASSERT_EQ(handle, chandle);
  31. static_assert(std::is_same_v<entt::registry *, decltype(handle.registry())>);
  32. static_assert(std::is_same_v<const entt::registry *, decltype(chandle.registry())>);
  33. }
  34. TEST(BasicHandle, Invalidation) {
  35. entt::handle handle;
  36. ASSERT_FALSE(handle);
  37. ASSERT_EQ(handle.registry(), nullptr);
  38. ASSERT_EQ(handle.entity(), entt::entity{entt::null});
  39. entt::registry registry;
  40. const auto entity = registry.create();
  41. handle = { registry, entity };
  42. ASSERT_TRUE(handle);
  43. ASSERT_NE(handle.registry(), nullptr);
  44. ASSERT_NE(handle.entity(), entt::entity{entt::null});
  45. handle = {};
  46. ASSERT_FALSE(handle);
  47. ASSERT_EQ(handle.registry(), nullptr);
  48. ASSERT_EQ(handle.entity(), entt::entity{entt::null});
  49. }
  50. TEST(BasicHandle, Destruction) {
  51. using traits_type = entt::entt_traits<entt::entity>;
  52. entt::registry registry;
  53. const auto entity = registry.create();
  54. entt::handle handle{registry, entity};
  55. ASSERT_TRUE(handle);
  56. ASSERT_TRUE(handle.valid());
  57. ASSERT_NE(handle.registry(), nullptr);
  58. ASSERT_EQ(handle.entity(), entity);
  59. handle.destroy(traits_type::to_version(entity));
  60. ASSERT_FALSE(handle);
  61. ASSERT_FALSE(handle.valid());
  62. ASSERT_NE(handle.registry(), nullptr);
  63. ASSERT_EQ(handle.entity(), entity);
  64. ASSERT_EQ(registry.current(entity), typename entt::registry::version_type{});
  65. handle = entt::handle{registry, registry.create()};
  66. ASSERT_TRUE(handle);
  67. ASSERT_TRUE(handle.valid());
  68. ASSERT_NE(handle.registry(), nullptr);
  69. ASSERT_EQ(handle.entity(), entity);
  70. handle.destroy();
  71. ASSERT_FALSE(handle);
  72. ASSERT_FALSE(handle.valid());
  73. ASSERT_NE(handle.registry(), nullptr);
  74. ASSERT_EQ(handle.entity(), entity);
  75. ASSERT_NE(registry.current(entity), typename entt::registry::version_type{});
  76. }
  77. TEST(BasicHandle, Comparison) {
  78. entt::registry registry;
  79. const auto entity = registry.create();
  80. entt::handle handle{registry, entity};
  81. entt::const_handle chandle = handle;
  82. ASSERT_NE(handle, entt::handle{});
  83. ASSERT_FALSE(handle == entt::handle{});
  84. ASSERT_TRUE(handle != entt::handle{});
  85. ASSERT_NE(chandle, entt::const_handle{});
  86. ASSERT_FALSE(chandle == entt::const_handle{});
  87. ASSERT_TRUE(chandle != entt::const_handle{});
  88. ASSERT_EQ(handle, chandle);
  89. ASSERT_TRUE(handle == chandle);
  90. ASSERT_FALSE(handle != chandle);
  91. ASSERT_EQ(entt::handle{}, entt::const_handle{});
  92. ASSERT_TRUE(entt::handle{} == entt::const_handle{});
  93. ASSERT_FALSE(entt::handle{} != entt::const_handle{});
  94. handle = {};
  95. chandle = {};
  96. ASSERT_EQ(handle, entt::handle{});
  97. ASSERT_TRUE(handle == entt::handle{});
  98. ASSERT_FALSE(handle != entt::handle{});
  99. ASSERT_EQ(chandle, entt::const_handle{});
  100. ASSERT_TRUE(chandle == entt::const_handle{});
  101. ASSERT_FALSE(chandle != entt::const_handle{});
  102. entt::registry other;
  103. const auto entt = other.create();
  104. handle = { registry, entity };
  105. chandle = { other, entt };
  106. ASSERT_NE(handle, chandle);
  107. ASSERT_FALSE(chandle == handle);
  108. ASSERT_TRUE(chandle != handle);
  109. ASSERT_EQ(handle.entity(), chandle.entity());
  110. ASSERT_NE(handle.registry(), chandle.registry());
  111. }
  112. TEST(BasicHandle, Component) {
  113. entt::registry registry;
  114. const auto entity = registry.create();
  115. entt::handle_view<int, char, double> handle{registry, entity};
  116. ASSERT_EQ(3, handle.emplace<int>(3));
  117. ASSERT_EQ('c', handle.emplace_or_replace<char>('c'));
  118. ASSERT_EQ(.3, handle.emplace_or_replace<double>(.3));
  119. const auto &patched = handle.patch<int>([](auto &comp) { comp = 42; });
  120. ASSERT_EQ(42, patched);
  121. ASSERT_EQ('a', handle.replace<char>('a'));
  122. ASSERT_TRUE((handle.all_of<int, char, double>()));
  123. ASSERT_EQ((std::make_tuple(42, 'a', .3)), (handle.get<int, char, double>()));
  124. handle.erase<char, double>();
  125. ASSERT_TRUE((registry.empty<char, double>()));
  126. ASSERT_EQ(0u, (handle.remove<char, double>()));
  127. handle.visit([](auto info) { ASSERT_EQ(entt::type_id<int>(), info); });
  128. ASSERT_TRUE((handle.any_of<int, char, double>()));
  129. ASSERT_FALSE((handle.all_of<int, char, double>()));
  130. ASSERT_FALSE(handle.orphan());
  131. ASSERT_EQ(1u, (handle.remove<int>()));
  132. ASSERT_DEATH(handle.erase<int>(), "");
  133. ASSERT_TRUE(registry.empty<int>());
  134. ASSERT_TRUE(handle.orphan());
  135. ASSERT_EQ(42, handle.get_or_emplace<int>(42));
  136. ASSERT_EQ(42, handle.get_or_emplace<int>(1));
  137. ASSERT_EQ(42, handle.get<int>());
  138. ASSERT_EQ(42, *handle.try_get<int>());
  139. ASSERT_EQ(nullptr, handle.try_get<char>());
  140. ASSERT_EQ(nullptr, std::get<1>(handle.try_get<int, char, double>()));
  141. }
  142. TEST(BasicHandle, FromEntity) {
  143. entt::registry registry;
  144. const auto entity = registry.create();
  145. registry.emplace<int>(entity, 42);
  146. registry.emplace<char>(entity, 'c');
  147. entt::handle handle{registry, entity};
  148. ASSERT_TRUE(handle);
  149. ASSERT_EQ(entity, handle.entity());
  150. ASSERT_TRUE((handle.all_of<int, char>()));
  151. ASSERT_EQ(handle.get<int>(), 42);
  152. ASSERT_EQ(handle.get<char>(), 'c');
  153. }
  154. TEST(BasicHandle, Lifetime) {
  155. entt::registry registry;
  156. const auto entity = registry.create();
  157. auto *handle = new entt::handle{registry, entity};
  158. handle->emplace<int>();
  159. ASSERT_FALSE(registry.empty<int>());
  160. ASSERT_FALSE(registry.empty());
  161. registry.each([handle](const auto e) {
  162. ASSERT_EQ(handle->entity(), e);
  163. });
  164. delete handle;
  165. ASSERT_FALSE(registry.empty<int>());
  166. ASSERT_FALSE(registry.empty());
  167. }
  168. TEST(BasicHandle, ImplicitConversions) {
  169. entt::registry registry;
  170. const entt::handle handle{registry, registry.create()};
  171. const entt::const_handle chandle = handle;
  172. const entt::handle_view<int, char> vhandle = handle;
  173. const entt::const_handle_view<int> cvhandle = vhandle;
  174. handle.emplace<int>(42);
  175. ASSERT_EQ(handle.get<int>(), chandle.get<int>());
  176. ASSERT_EQ(chandle.get<int>(), vhandle.get<int>());
  177. ASSERT_EQ(vhandle.get<int>(), cvhandle.get<int>());
  178. ASSERT_EQ(cvhandle.get<int>(), 42);
  179. }