handle.cpp 7.1 KB

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