view.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #include <gtest/gtest.h>
  2. #include <entt/entity/registry.hpp>
  3. #include <entt/entity/view.hpp>
  4. TEST(View, SingleComponent) {
  5. entt::DefaultRegistry registry;
  6. auto view = registry.view<char>();
  7. const auto e0 = registry.create();
  8. const auto e1 = registry.create();
  9. ASSERT_TRUE(view.empty());
  10. registry.assign<int>(e1);
  11. registry.assign<char>(e1);
  12. ASSERT_NO_THROW(registry.view<char>().begin()++);
  13. ASSERT_NO_THROW(++registry.view<char>().begin());
  14. ASSERT_NE(view.begin(), view.end());
  15. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  16. ASSERT_FALSE(view.empty());
  17. registry.assign<char>(e0);
  18. ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
  19. view.get(e0) = '1';
  20. view.get(e1) = '2';
  21. for(auto entity: view) {
  22. const auto &cview = static_cast<const decltype(view) &>(view);
  23. ASSERT_TRUE(cview.get(entity) == '1' || cview.get(entity) == '2');
  24. }
  25. ASSERT_EQ(*(view.data() + 0), e1);
  26. ASSERT_EQ(*(view.data() + 1), e0);
  27. ASSERT_EQ(*(view.raw() + 0), '2');
  28. ASSERT_EQ(*(static_cast<const decltype(view) &>(view).raw() + 1), '1');
  29. registry.remove<char>(e0);
  30. registry.remove<char>(e1);
  31. ASSERT_EQ(view.begin(), view.end());
  32. ASSERT_TRUE(view.empty());
  33. }
  34. TEST(View, SingleComponentContains) {
  35. entt::DefaultRegistry registry;
  36. const auto e0 = registry.create();
  37. registry.assign<int>(e0);
  38. const auto e1 = registry.create();
  39. registry.assign<int>(e1);
  40. registry.destroy(e0);
  41. auto view = registry.view<int>();
  42. ASSERT_FALSE(view.contains(e0));
  43. ASSERT_TRUE(view.contains(e1));
  44. }
  45. TEST(View, SingleComponentEmpty) {
  46. entt::DefaultRegistry registry;
  47. const auto e0 = registry.create();
  48. registry.assign<char>(e0);
  49. registry.assign<double>(e0);
  50. const auto e1 = registry.create();
  51. registry.assign<char>(e1);
  52. auto view = registry.view<int>();
  53. ASSERT_EQ(view.size(), entt::DefaultRegistry::size_type{0});
  54. for(auto entity: view) {
  55. (void)entity;
  56. FAIL();
  57. }
  58. }
  59. TEST(View, SingleComponentEach) {
  60. entt::DefaultRegistry registry;
  61. const auto e0 = registry.create();
  62. registry.assign<int>(e0);
  63. registry.assign<char>(e0);
  64. const auto e1 = registry.create();
  65. registry.assign<int>(e1);
  66. registry.assign<char>(e1);
  67. auto view = registry.view<int>();
  68. const auto &cview = static_cast<const decltype(view) &>(view);
  69. std::size_t cnt = 0;
  70. view.each([&cnt](auto, int &) { ++cnt; });
  71. ASSERT_EQ(cnt, std::size_t{2});
  72. cview.each([&cnt](auto, const int &) { --cnt; });
  73. ASSERT_EQ(cnt, std::size_t{0});
  74. }
  75. TEST(View, MultipleComponent) {
  76. entt::DefaultRegistry registry;
  77. auto view = registry.view<int, char>();
  78. ASSERT_TRUE(view.empty());
  79. const auto e0 = registry.create();
  80. registry.assign<char>(e0);
  81. const auto e1 = registry.create();
  82. registry.assign<int>(e1);
  83. ASSERT_FALSE(view.empty());
  84. registry.assign<char>(e1);
  85. auto it = registry.view<char>().begin();
  86. ASSERT_EQ(*it, e1);
  87. ASSERT_EQ(*(it+1), e0);
  88. ASSERT_EQ(it += 2, registry.view<char>().end());
  89. ASSERT_NO_THROW((registry.view<int, char>().begin()++));
  90. ASSERT_NO_THROW((++registry.view<int, char>().begin()));
  91. ASSERT_NE(view.begin(), view.end());
  92. ASSERT_EQ(view.begin()+1, view.end());
  93. ASSERT_EQ(view.size(), decltype(view.size()){1});
  94. registry.get<char>(e0) = '1';
  95. registry.get<char>(e1) = '2';
  96. registry.get<int>(e1) = 42;
  97. for(auto entity: view) {
  98. const auto &cview = static_cast<const decltype(view) &>(view);
  99. ASSERT_EQ(std::get<0>(cview.get<int, char>(entity)), 42);
  100. ASSERT_EQ(std::get<1>(view.get<int, char>(entity)), '2');
  101. ASSERT_EQ(cview.get<char>(entity), '2');
  102. }
  103. registry.remove<char>(e0);
  104. registry.remove<char>(e1);
  105. view.reset();
  106. ASSERT_EQ(view.begin(), view.end());
  107. ASSERT_TRUE(view.empty());
  108. }
  109. TEST(View, MultipleComponentContains) {
  110. entt::DefaultRegistry registry;
  111. const auto e0 = registry.create();
  112. registry.assign<int>(e0);
  113. registry.assign<char>(e0);
  114. const auto e1 = registry.create();
  115. registry.assign<int>(e1);
  116. registry.assign<char>(e1);
  117. registry.destroy(e0);
  118. auto view = registry.view<int, char>();
  119. ASSERT_FALSE(view.contains(e0));
  120. ASSERT_TRUE(view.contains(e1));
  121. }
  122. TEST(View, MultipleComponentEmpty) {
  123. entt::DefaultRegistry registry;
  124. const auto e0 = registry.create();
  125. registry.assign<double>(e0);
  126. registry.assign<int>(e0);
  127. registry.assign<float>(e0);
  128. const auto e1 = registry.create();
  129. registry.assign<char>(e1);
  130. registry.assign<float>(e1);
  131. auto view = registry.view<char, int, float>();
  132. for(auto entity: view) {
  133. (void)entity;
  134. FAIL();
  135. }
  136. }
  137. TEST(View, MultipleComponentEach) {
  138. entt::DefaultRegistry registry;
  139. const auto e0 = registry.create();
  140. registry.assign<int>(e0);
  141. registry.assign<char>(e0);
  142. const auto e1 = registry.create();
  143. registry.assign<int>(e1);
  144. registry.assign<char>(e1);
  145. auto view = registry.view<int, char>();
  146. const auto &cview = static_cast<const decltype(view) &>(view);
  147. std::size_t cnt = 0;
  148. view.each([&cnt](auto, int &, char &) { ++cnt; });
  149. ASSERT_EQ(cnt, std::size_t{2});
  150. cview.each([&cnt](auto, const int &, const char &) { --cnt; });
  151. ASSERT_EQ(cnt, std::size_t{0});
  152. }
  153. TEST(PersistentView, Prepare) {
  154. entt::DefaultRegistry registry;
  155. registry.prepare<int, char>();
  156. auto view = registry.persistent<int, char>();
  157. ASSERT_TRUE(view.empty());
  158. const auto e0 = registry.create();
  159. registry.assign<char>(e0);
  160. const auto e1 = registry.create();
  161. registry.assign<int>(e1);
  162. registry.assign<char>(e1);
  163. ASSERT_FALSE(view.empty());
  164. ASSERT_NO_THROW((registry.persistent<int, char>().begin()++));
  165. ASSERT_NO_THROW((++registry.persistent<int, char>().begin()));
  166. ASSERT_NE(view.begin(), view.end());
  167. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  168. registry.assign<int>(e0);
  169. ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
  170. registry.remove<int>(e0);
  171. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  172. registry.get<char>(e0) = '1';
  173. registry.get<char>(e1) = '2';
  174. registry.get<int>(e1) = 42;
  175. for(auto entity: view) {
  176. const auto &cview = static_cast<const decltype(view) &>(view);
  177. ASSERT_EQ(std::get<0>(cview.get<int, char>(entity)), 42);
  178. ASSERT_EQ(std::get<1>(view.get<int, char>(entity)), '2');
  179. ASSERT_EQ(cview.get<char>(entity), '2');
  180. }
  181. ASSERT_EQ(*(view.data() + 0), e1);
  182. registry.remove<char>(e0);
  183. registry.remove<char>(e1);
  184. ASSERT_EQ(view.begin(), view.end());
  185. ASSERT_TRUE(view.empty());
  186. }
  187. TEST(PersistentView, NoPrepare) {
  188. entt::DefaultRegistry registry;
  189. auto view = registry.persistent<int, char>();
  190. ASSERT_TRUE(view.empty());
  191. const auto e0 = registry.create();
  192. registry.assign<char>(e0);
  193. const auto e1 = registry.create();
  194. registry.assign<int>(e1);
  195. registry.assign<char>(e1);
  196. ASSERT_FALSE(view.empty());
  197. ASSERT_NO_THROW((registry.persistent<int, char>().begin()++));
  198. ASSERT_NO_THROW((++registry.persistent<int, char>().begin()));
  199. ASSERT_NE(view.begin(), view.end());
  200. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  201. registry.assign<int>(e0);
  202. ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
  203. registry.remove<int>(e0);
  204. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  205. registry.get<char>(e0) = '1';
  206. registry.get<char>(e1) = '2';
  207. registry.get<int>(e1) = 42;
  208. for(auto entity: view) {
  209. const auto &cview = static_cast<const decltype(view) &>(view);
  210. ASSERT_EQ(std::get<0>(cview.get<int, char>(entity)), 42);
  211. ASSERT_EQ(std::get<1>(view.get<int, char>(entity)), '2');
  212. ASSERT_EQ(cview.get<char>(entity), '2');
  213. }
  214. ASSERT_EQ(*(view.data() + 0), e1);
  215. registry.remove<char>(e0);
  216. registry.remove<char>(e1);
  217. ASSERT_EQ(view.begin(), view.end());
  218. ASSERT_TRUE(view.empty());
  219. }
  220. TEST(PersistentView, Contains) {
  221. entt::DefaultRegistry registry;
  222. const auto e0 = registry.create();
  223. registry.assign<int>(e0);
  224. registry.assign<char>(e0);
  225. const auto e1 = registry.create();
  226. registry.assign<int>(e1);
  227. registry.assign<char>(e1);
  228. registry.destroy(e0);
  229. auto view = registry.persistent<int, char>();
  230. ASSERT_FALSE(view.contains(e0));
  231. ASSERT_TRUE(view.contains(e1));
  232. }
  233. TEST(PersistentView, Empty) {
  234. entt::DefaultRegistry registry;
  235. const auto e0 = registry.create();
  236. registry.assign<double>(e0);
  237. registry.assign<int>(e0);
  238. registry.assign<float>(e0);
  239. const auto e1 = registry.create();
  240. registry.assign<char>(e1);
  241. registry.assign<float>(e1);
  242. for(auto entity: registry.persistent<char, int, float>()) {
  243. (void)entity;
  244. FAIL();
  245. }
  246. for(auto entity: registry.persistent<double, char, int, float>()) {
  247. (void)entity;
  248. FAIL();
  249. }
  250. }
  251. TEST(PersistentView, Each) {
  252. entt::DefaultRegistry registry;
  253. registry.prepare<int, char>();
  254. const auto e0 = registry.create();
  255. registry.assign<int>(e0);
  256. registry.assign<char>(e0);
  257. const auto e1 = registry.create();
  258. registry.assign<int>(e1);
  259. registry.assign<char>(e1);
  260. auto view = registry.persistent<int, char>();
  261. const auto &cview = static_cast<const decltype(view) &>(view);
  262. std::size_t cnt = 0;
  263. view.each([&cnt](auto, int &, char &) { ++cnt; });
  264. ASSERT_EQ(cnt, std::size_t{2});
  265. cview.each([&cnt](auto, const int &, const char &) { --cnt; });
  266. ASSERT_EQ(cnt, std::size_t{0});
  267. }
  268. TEST(PersistentView, Sort) {
  269. entt::DefaultRegistry registry;
  270. registry.prepare<int, unsigned int>();
  271. const auto e0 = registry.create();
  272. const auto e1 = registry.create();
  273. const auto e2 = registry.create();
  274. auto uval = 0u;
  275. auto ival = 0;
  276. registry.assign<unsigned int>(e0, uval++);
  277. registry.assign<unsigned int>(e1, uval++);
  278. registry.assign<unsigned int>(e2, uval++);
  279. registry.assign<int>(e0, ival++);
  280. registry.assign<int>(e1, ival++);
  281. registry.assign<int>(e2, ival++);
  282. auto view = registry.persistent<int, unsigned int>();
  283. for(auto entity: view) {
  284. ASSERT_EQ(view.get<unsigned int>(entity), --uval);
  285. ASSERT_EQ(view.get<int>(entity), --ival);
  286. }
  287. registry.sort<unsigned int>(std::less<unsigned int>{});
  288. view.sort<unsigned int>();
  289. for(auto entity: view) {
  290. ASSERT_EQ(view.get<unsigned int>(entity), uval++);
  291. ASSERT_EQ(view.get<int>(entity), ival++);
  292. }
  293. }
  294. TEST(RawView, Functionalities) {
  295. entt::DefaultRegistry registry;
  296. auto view = registry.raw<char>();
  297. ASSERT_TRUE(view.empty());
  298. const auto e0 = registry.create();
  299. const auto e1 = registry.create();
  300. registry.assign<int>(e1);
  301. registry.assign<char>(e1);
  302. ASSERT_FALSE(view.empty());
  303. ASSERT_NO_THROW(registry.raw<char>().begin()++);
  304. ASSERT_NO_THROW(++registry.raw<char>().begin());
  305. ASSERT_NE(view.begin(), view.end());
  306. ASSERT_EQ(view.size(), typename decltype(view)::size_type{1});
  307. registry.assign<char>(e0);
  308. ASSERT_EQ(view.size(), typename decltype(view)::size_type{2});
  309. registry.get<char>(e0) = '1';
  310. registry.get<char>(e1) = '2';
  311. for(auto &&component: view) {
  312. ASSERT_TRUE(component == '1' || component == '2');
  313. }
  314. ASSERT_EQ(*(view.data() + 0), e1);
  315. ASSERT_EQ(*(view.data() + 1), e0);
  316. ASSERT_EQ(*(view.raw() + 0), '2');
  317. ASSERT_EQ(*(static_cast<const decltype(view) &>(view).raw() + 1), '1');
  318. for(auto &&component: view) {
  319. // verifies that iterators return references to components
  320. component = '0';
  321. }
  322. for(auto &&component: view) {
  323. ASSERT_TRUE(component == '0');
  324. }
  325. registry.remove<char>(e0);
  326. registry.remove<char>(e1);
  327. ASSERT_EQ(view.begin(), view.end());
  328. ASSERT_TRUE(view.empty());
  329. }
  330. TEST(RawView, Empty) {
  331. entt::DefaultRegistry registry;
  332. const auto e0 = registry.create();
  333. registry.assign<char>(e0);
  334. registry.assign<double>(e0);
  335. const auto e1 = registry.create();
  336. registry.assign<char>(e1);
  337. auto view = registry.raw<int>();
  338. ASSERT_EQ(view.size(), entt::DefaultRegistry::size_type{0});
  339. for(auto &&component: view) {
  340. (void)component;
  341. FAIL();
  342. }
  343. }