registry.cpp 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  1. #include <unordered_map>
  2. #include <unordered_set>
  3. #include <functional>
  4. #include <iterator>
  5. #include <memory>
  6. #include <cstdint>
  7. #include <type_traits>
  8. #include <gtest/gtest.h>
  9. #include <entt/entity/registry.hpp>
  10. #include <entt/entity/entity.hpp>
  11. ENTT_NAMED_TYPE(int)
  12. struct listener {
  13. template<typename Component>
  14. void incr(entt::registry &registry, entt::entity entity, const Component &) {
  15. ASSERT_TRUE(registry.valid(entity));
  16. ASSERT_TRUE(registry.has<Component>(entity));
  17. last = entity;
  18. ++counter;
  19. }
  20. template<typename Component>
  21. void decr(entt::registry &registry, entt::entity entity) {
  22. ASSERT_TRUE(registry.valid(entity));
  23. ASSERT_TRUE(registry.has<Component>(entity));
  24. last = entity;
  25. --counter;
  26. }
  27. entt::entity last;
  28. int counter{0};
  29. };
  30. TEST(Registry, Context) {
  31. entt::registry registry;
  32. ASSERT_EQ(registry.try_ctx<char>(), nullptr);
  33. ASSERT_EQ(registry.try_ctx<int>(), nullptr);
  34. ASSERT_EQ(registry.try_ctx<double>(), nullptr);
  35. registry.set<char>();
  36. registry.set<int>();
  37. registry.set<double>();
  38. ASSERT_NE(registry.try_ctx<char>(), nullptr);
  39. ASSERT_NE(registry.try_ctx<int>(), nullptr);
  40. ASSERT_NE(registry.try_ctx<double>(), nullptr);
  41. registry.unset<int>();
  42. registry.unset<double>();
  43. ASSERT_NE(registry.try_ctx<char>(), nullptr);
  44. ASSERT_EQ(registry.try_ctx<int>(), nullptr);
  45. ASSERT_EQ(registry.try_ctx<double>(), nullptr);
  46. registry.set<char>('c');
  47. registry.set<int>(0);
  48. registry.set<double>(1.);
  49. registry.set<int>(42);
  50. ASSERT_EQ(registry.ctx<char>(), 'c');
  51. ASSERT_NE(registry.try_ctx<char>(), nullptr);
  52. ASSERT_EQ(registry.try_ctx<char>(), &registry.ctx<char>());
  53. ASSERT_EQ(registry.ctx<char>(), std::as_const(registry).ctx<char>());
  54. ASSERT_EQ(registry.ctx<int>(), 42);
  55. ASSERT_NE(registry.try_ctx<int>(), nullptr);
  56. ASSERT_EQ(registry.try_ctx<int>(), &registry.ctx<int>());
  57. ASSERT_EQ(registry.ctx<int>(), std::as_const(registry).ctx<int>());
  58. ASSERT_EQ(registry.ctx<double>(), 1.);
  59. ASSERT_NE(registry.try_ctx<double>(), nullptr);
  60. ASSERT_EQ(registry.try_ctx<double>(), &registry.ctx<double>());
  61. ASSERT_EQ(registry.ctx<double>(), std::as_const(registry).ctx<double>());
  62. ASSERT_EQ(registry.try_ctx<float>(), nullptr);
  63. }
  64. TEST(Registry, Types) {
  65. entt::registry registry;
  66. ASSERT_EQ(registry.type<int>(), registry.type<int>());
  67. ASSERT_NE(registry.type<double>(), registry.type<int>());
  68. }
  69. TEST(Registry, Functionalities) {
  70. entt::registry registry;
  71. ASSERT_EQ(registry.size(), entt::registry::size_type{0});
  72. ASSERT_EQ(registry.alive(), entt::registry::size_type{0});
  73. ASSERT_NO_THROW(registry.reserve(42));
  74. ASSERT_NO_THROW(registry.reserve<int>(8));
  75. ASSERT_NO_THROW(registry.reserve<char>(8));
  76. ASSERT_TRUE(registry.empty());
  77. ASSERT_EQ(registry.capacity(), entt::registry::size_type{42});
  78. ASSERT_EQ(registry.capacity<int>(), entt::registry::size_type{8});
  79. ASSERT_EQ(registry.capacity<char>(), entt::registry::size_type{8});
  80. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{0});
  81. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{0});
  82. ASSERT_TRUE(registry.empty<int>());
  83. ASSERT_TRUE(registry.empty<char>());
  84. const auto e0 = registry.create();
  85. const auto e1 = registry.create();
  86. registry.assign<int>(e1);
  87. registry.assign<char>(e1);
  88. ASSERT_TRUE(registry.has<>(e0));
  89. ASSERT_TRUE(registry.has<>(e1));
  90. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{1});
  91. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{1});
  92. ASSERT_FALSE(registry.empty<int>());
  93. ASSERT_FALSE(registry.empty<char>());
  94. ASSERT_NE(e0, e1);
  95. ASSERT_FALSE(registry.has<int>(e0));
  96. ASSERT_TRUE(registry.has<int>(e1));
  97. ASSERT_FALSE(registry.has<char>(e0));
  98. ASSERT_TRUE(registry.has<char>(e1));
  99. ASSERT_FALSE((registry.has<int, char>(e0)));
  100. ASSERT_TRUE((registry.has<int, char>(e1)));
  101. ASSERT_EQ(registry.try_get<int>(e0), nullptr);
  102. ASSERT_NE(registry.try_get<int>(e1), nullptr);
  103. ASSERT_EQ(registry.try_get<char>(e0), nullptr);
  104. ASSERT_NE(registry.try_get<char>(e1), nullptr);
  105. ASSERT_EQ(registry.try_get<double>(e0), nullptr);
  106. ASSERT_EQ(registry.try_get<double>(e1), nullptr);
  107. ASSERT_EQ(registry.assign<int>(e0, 42), 42);
  108. ASSERT_EQ(registry.assign<char>(e0, 'c'), 'c');
  109. ASSERT_NO_THROW(registry.remove<int>(e1));
  110. ASSERT_NO_THROW(registry.remove<char>(e1));
  111. ASSERT_TRUE(registry.has<int>(e0));
  112. ASSERT_FALSE(registry.has<int>(e1));
  113. ASSERT_TRUE(registry.has<char>(e0));
  114. ASSERT_FALSE(registry.has<char>(e1));
  115. ASSERT_TRUE((registry.has<int, char>(e0)));
  116. ASSERT_FALSE((registry.has<int, char>(e1)));
  117. const auto e2 = registry.create();
  118. registry.assign_or_replace<int>(e2, registry.get<int>(e0));
  119. registry.assign_or_replace<char>(e2, registry.get<char>(e0));
  120. ASSERT_TRUE(registry.has<int>(e2));
  121. ASSERT_TRUE(registry.has<char>(e2));
  122. ASSERT_EQ(registry.get<int>(e0), 42);
  123. ASSERT_EQ(registry.get<char>(e0), 'c');
  124. ASSERT_NE(registry.try_get<int>(e0), nullptr);
  125. ASSERT_NE(registry.try_get<char>(e0), nullptr);
  126. ASSERT_EQ(registry.try_get<double>(e0), nullptr);
  127. ASSERT_EQ(*registry.try_get<int>(e0), 42);
  128. ASSERT_EQ(*registry.try_get<char>(e0), 'c');
  129. ASSERT_EQ(std::get<0>(registry.get<int, char>(e0)), 42);
  130. ASSERT_EQ(*std::get<0>(registry.try_get<int, char, double>(e0)), 42);
  131. ASSERT_EQ(std::get<1>(static_cast<const entt::registry &>(registry).get<int, char>(e0)), 'c');
  132. ASSERT_EQ(*std::get<1>(static_cast<const entt::registry &>(registry).try_get<int, char, double>(e0)), 'c');
  133. ASSERT_EQ(registry.get<int>(e0), registry.get<int>(e2));
  134. ASSERT_EQ(registry.get<char>(e0), registry.get<char>(e2));
  135. ASSERT_NE(&registry.get<int>(e0), &registry.get<int>(e2));
  136. ASSERT_NE(&registry.get<char>(e0), &registry.get<char>(e2));
  137. ASSERT_NO_THROW(registry.replace<int>(e0, 0));
  138. ASSERT_EQ(registry.get<int>(e0), 0);
  139. ASSERT_NO_THROW(registry.assign_or_replace<int>(e0, 1));
  140. ASSERT_NO_THROW(registry.assign_or_replace<int>(e1, 1));
  141. ASSERT_EQ(static_cast<const entt::registry &>(registry).get<int>(e0), 1);
  142. ASSERT_EQ(static_cast<const entt::registry &>(registry).get<int>(e1), 1);
  143. ASSERT_EQ(registry.size(), entt::registry::size_type{3});
  144. ASSERT_EQ(registry.alive(), entt::registry::size_type{3});
  145. ASSERT_FALSE(registry.empty());
  146. ASSERT_EQ(registry.version(e2), entt::registry::version_type{0});
  147. ASSERT_EQ(registry.current(e2), entt::registry::version_type{0});
  148. ASSERT_NO_THROW(registry.destroy(e2));
  149. ASSERT_EQ(registry.version(e2), entt::registry::version_type{0});
  150. ASSERT_EQ(registry.current(e2), entt::registry::version_type{1});
  151. ASSERT_TRUE(registry.valid(e0));
  152. ASSERT_TRUE(registry.valid(e1));
  153. ASSERT_FALSE(registry.valid(e2));
  154. ASSERT_EQ(registry.size(), entt::registry::size_type{3});
  155. ASSERT_EQ(registry.alive(), entt::registry::size_type{2});
  156. ASSERT_FALSE(registry.empty());
  157. ASSERT_NO_THROW(registry.reset());
  158. ASSERT_EQ(registry.size(), entt::registry::size_type{3});
  159. ASSERT_EQ(registry.alive(), entt::registry::size_type{0});
  160. ASSERT_TRUE(registry.empty());
  161. const auto e3 = registry.create();
  162. ASSERT_EQ(registry.get_or_assign<int>(e3, 3), 3);
  163. ASSERT_EQ(registry.get_or_assign<char>(e3, 'c'), 'c');
  164. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{1});
  165. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{1});
  166. ASSERT_FALSE(registry.empty<int>());
  167. ASSERT_FALSE(registry.empty<char>());
  168. ASSERT_TRUE(registry.has<int>(e3));
  169. ASSERT_TRUE(registry.has<char>(e3));
  170. ASSERT_EQ(registry.get<int>(e3), 3);
  171. ASSERT_EQ(registry.get<char>(e3), 'c');
  172. ASSERT_NO_THROW(registry.reset<int>());
  173. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{0});
  174. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{1});
  175. ASSERT_TRUE(registry.empty<int>());
  176. ASSERT_FALSE(registry.empty<char>());
  177. ASSERT_NO_THROW(registry.reset());
  178. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{0});
  179. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{0});
  180. ASSERT_TRUE(registry.empty<int>());
  181. ASSERT_TRUE(registry.empty<char>());
  182. const auto e4 = registry.create();
  183. const auto e5 = registry.create();
  184. registry.assign<int>(e4);
  185. ASSERT_NO_THROW(registry.reset<int>(e4));
  186. ASSERT_NO_THROW(registry.reset<int>(e5));
  187. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{0});
  188. ASSERT_EQ(registry.size<char>(), entt::registry::size_type{0});
  189. ASSERT_TRUE(registry.empty<int>());
  190. ASSERT_EQ(registry.capacity<int>(), entt::registry::size_type{8});
  191. ASSERT_EQ(registry.capacity<char>(), entt::registry::size_type{8});
  192. registry.shrink_to_fit<int>();
  193. registry.shrink_to_fit<char>();
  194. ASSERT_EQ(registry.capacity<int>(), entt::registry::size_type{});
  195. ASSERT_EQ(registry.capacity<char>(), entt::registry::size_type{});
  196. }
  197. TEST(Registry, Identifiers) {
  198. entt::registry registry;
  199. const auto pre = registry.create();
  200. ASSERT_EQ(pre, registry.entity(pre));
  201. registry.destroy(pre);
  202. const auto post = registry.create();
  203. ASSERT_NE(pre, post);
  204. ASSERT_EQ(registry.entity(pre), registry.entity(post));
  205. ASSERT_NE(registry.version(pre), registry.version(post));
  206. ASSERT_NE(registry.version(pre), registry.current(pre));
  207. ASSERT_EQ(registry.version(post), registry.current(post));
  208. }
  209. TEST(Registry, RawData) {
  210. entt::registry registry;
  211. const auto entity = registry.create();
  212. ASSERT_EQ(registry.raw<int>(), nullptr);
  213. ASSERT_EQ(std::as_const(registry).raw<int>(), nullptr);
  214. ASSERT_EQ(std::as_const(registry).data<int>(), nullptr);
  215. registry.assign<int>(entity, 42);
  216. ASSERT_NE(registry.raw<int>(), nullptr);
  217. ASSERT_NE(std::as_const(registry).raw<int>(), nullptr);
  218. ASSERT_NE(std::as_const(registry).data<int>(), nullptr);
  219. ASSERT_EQ(*registry.raw<int>(), 42);
  220. ASSERT_EQ(*std::as_const(registry).raw<int>(), 42);
  221. ASSERT_EQ(*std::as_const(registry).data<int>(), entity);
  222. }
  223. TEST(Registry, CreateDestroyCornerCase) {
  224. entt::registry registry;
  225. const auto e0 = registry.create();
  226. const auto e1 = registry.create();
  227. registry.destroy(e0);
  228. registry.destroy(e1);
  229. registry.each([](auto) { FAIL(); });
  230. ASSERT_EQ(registry.current(e0), entt::registry::version_type{1});
  231. ASSERT_EQ(registry.current(e1), entt::registry::version_type{1});
  232. }
  233. TEST(Registry, VersionOverflow) {
  234. entt::registry registry;
  235. const auto entity = registry.create();
  236. registry.destroy(entity);
  237. ASSERT_EQ(registry.version(entity), entt::registry::version_type{});
  238. for(auto i = entt::entt_traits<entt::entity>::version_mask; i; --i) {
  239. ASSERT_NE(registry.current(entity), registry.version(entity));
  240. registry.destroy(registry.create());
  241. }
  242. ASSERT_EQ(registry.current(entity), registry.version(entity));
  243. }
  244. TEST(Registry, Each) {
  245. entt::registry registry;
  246. entt::registry::size_type tot;
  247. entt::registry::size_type match;
  248. registry.create();
  249. registry.assign<int>(registry.create());
  250. registry.create();
  251. registry.assign<int>(registry.create());
  252. registry.create();
  253. tot = 0u;
  254. match = 0u;
  255. registry.each([&](auto entity) {
  256. if(registry.has<int>(entity)) { ++match; }
  257. registry.create();
  258. ++tot;
  259. });
  260. ASSERT_EQ(tot, 5u);
  261. ASSERT_EQ(match, 2u);
  262. tot = 0u;
  263. match = 0u;
  264. registry.each([&](auto entity) {
  265. if(registry.has<int>(entity)) {
  266. registry.destroy(entity);
  267. ++match;
  268. }
  269. ++tot;
  270. });
  271. ASSERT_EQ(tot, 10u);
  272. ASSERT_EQ(match, 2u);
  273. tot = 0u;
  274. match = 0u;
  275. registry.each([&](auto entity) {
  276. if(registry.has<int>(entity)) { ++match; }
  277. registry.destroy(entity);
  278. ++tot;
  279. });
  280. ASSERT_EQ(tot, 8u);
  281. ASSERT_EQ(match, 0u);
  282. registry.each([&](auto) { FAIL(); });
  283. }
  284. TEST(Registry, Orphans) {
  285. entt::registry registry;
  286. entt::registry::size_type tot{};
  287. registry.assign<int>(registry.create());
  288. registry.create();
  289. registry.assign<int>(registry.create());
  290. registry.orphans([&](auto) { ++tot; });
  291. ASSERT_EQ(tot, 1u);
  292. tot = {};
  293. registry.each([&](auto entity) { registry.reset<int>(entity); });
  294. registry.orphans([&](auto) { ++tot; });
  295. ASSERT_EQ(tot, 3u);
  296. registry.reset();
  297. tot = {};
  298. registry.orphans([&](auto) { ++tot; });
  299. ASSERT_EQ(tot, 0u);
  300. }
  301. TEST(Registry, CreateDestroyEntities) {
  302. entt::registry registry;
  303. entt::entity pre{}, post{};
  304. for(int i = 0; i < 10; ++i) {
  305. const auto entity = registry.create();
  306. registry.assign<double>(entity);
  307. }
  308. registry.reset();
  309. for(int i = 0; i < 7; ++i) {
  310. const auto entity = registry.create();
  311. registry.assign<int>(entity);
  312. if(i == 3) { pre = entity; }
  313. }
  314. registry.reset();
  315. for(int i = 0; i < 5; ++i) {
  316. const auto entity = registry.create();
  317. if(i == 3) { post = entity; }
  318. }
  319. ASSERT_FALSE(registry.valid(pre));
  320. ASSERT_TRUE(registry.valid(post));
  321. ASSERT_NE(registry.version(pre), registry.version(post));
  322. ASSERT_EQ(registry.version(pre) + 1, registry.version(post));
  323. ASSERT_EQ(registry.current(pre), registry.current(post));
  324. }
  325. TEST(Registry, View) {
  326. entt::registry registry;
  327. auto mview = registry.view<int, char>();
  328. auto iview = registry.view<int>();
  329. auto cview = registry.view<char>();
  330. const auto e0 = registry.create();
  331. registry.assign<int>(e0, 0);
  332. registry.assign<char>(e0, 'c');
  333. const auto e1 = registry.create();
  334. registry.assign<int>(e1, 0);
  335. const auto e2 = registry.create();
  336. registry.assign<int>(e2, 0);
  337. registry.assign<char>(e2, 'c');
  338. ASSERT_EQ(iview.size(), decltype(iview)::size_type{3});
  339. ASSERT_EQ(cview.size(), decltype(cview)::size_type{2});
  340. decltype(mview)::size_type cnt{0};
  341. mview.each([&cnt](auto...) { ++cnt; });
  342. ASSERT_EQ(cnt, decltype(mview)::size_type{2});
  343. }
  344. TEST(Registry, NonOwningGroupInitOnFirstUse) {
  345. entt::registry registry;
  346. const auto e0 = registry.create();
  347. registry.assign<int>(e0, 0);
  348. registry.assign<char>(e0, 'c');
  349. const auto e1 = registry.create();
  350. registry.assign<int>(e1, 0);
  351. const auto e2 = registry.create();
  352. registry.assign<int>(e2, 0);
  353. registry.assign<char>(e2, 'c');
  354. ASSERT_FALSE(registry.owned<int>());
  355. ASSERT_FALSE(registry.owned<char>());
  356. auto group = registry.group<>(entt::get<int, char>);
  357. decltype(group)::size_type cnt{0};
  358. group.each([&cnt](auto...) { ++cnt; });
  359. ASSERT_FALSE(registry.owned<int>());
  360. ASSERT_FALSE(registry.owned<char>());
  361. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  362. }
  363. TEST(Registry, NonOwningGroupInitOnAssign) {
  364. entt::registry registry;
  365. auto group = registry.group<>(entt::get<int, char>);
  366. const auto e0 = registry.create();
  367. registry.assign<int>(e0, 0);
  368. registry.assign<char>(e0, 'c');
  369. const auto e1 = registry.create();
  370. registry.assign<int>(e1, 0);
  371. const auto e2 = registry.create();
  372. registry.assign<int>(e2, 0);
  373. registry.assign<char>(e2, 'c');
  374. ASSERT_FALSE(registry.owned<int>());
  375. ASSERT_FALSE(registry.owned<char>());
  376. decltype(group)::size_type cnt{0};
  377. group.each([&cnt](auto...) { ++cnt; });
  378. ASSERT_FALSE(registry.owned<int>());
  379. ASSERT_FALSE(registry.owned<char>());
  380. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  381. }
  382. TEST(Registry, FullOwningGroupInitOnFirstUse) {
  383. entt::registry registry;
  384. const auto e0 = registry.create();
  385. registry.assign<int>(e0, 0);
  386. registry.assign<char>(e0, 'c');
  387. const auto e1 = registry.create();
  388. registry.assign<int>(e1, 0);
  389. const auto e2 = registry.create();
  390. registry.assign<int>(e2, 0);
  391. registry.assign<char>(e2, 'c');
  392. ASSERT_FALSE(registry.owned<int>());
  393. ASSERT_FALSE(registry.owned<char>());
  394. auto group = registry.group<int, char>();
  395. decltype(group)::size_type cnt{0};
  396. group.each([&cnt](auto...) { ++cnt; });
  397. ASSERT_TRUE(registry.owned<int>());
  398. ASSERT_TRUE(registry.owned<char>());
  399. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  400. }
  401. TEST(Registry, FullOwningGroupInitOnAssign) {
  402. entt::registry registry;
  403. auto group = registry.group<int, char>();
  404. const auto e0 = registry.create();
  405. registry.assign<int>(e0, 0);
  406. registry.assign<char>(e0, 'c');
  407. const auto e1 = registry.create();
  408. registry.assign<int>(e1, 0);
  409. const auto e2 = registry.create();
  410. registry.assign<int>(e2, 0);
  411. registry.assign<char>(e2, 'c');
  412. ASSERT_TRUE(registry.owned<int>());
  413. ASSERT_TRUE(registry.owned<char>());
  414. decltype(group)::size_type cnt{0};
  415. group.each([&cnt](auto...) { ++cnt; });
  416. ASSERT_TRUE(registry.owned<int>());
  417. ASSERT_TRUE(registry.owned<char>());
  418. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  419. }
  420. TEST(Registry, PartialOwningGroupInitOnFirstUse) {
  421. entt::registry registry;
  422. const auto e0 = registry.create();
  423. registry.assign<int>(e0, 0);
  424. registry.assign<char>(e0, 'c');
  425. const auto e1 = registry.create();
  426. registry.assign<int>(e1, 1);
  427. const auto e2 = registry.create();
  428. registry.assign<int>(e2, 2);
  429. registry.assign<char>(e2, 'c');
  430. ASSERT_FALSE(registry.owned<int>());
  431. ASSERT_FALSE(registry.owned<char>());
  432. auto group = registry.group<int>(entt::get<char>);
  433. decltype(group)::size_type cnt{0};
  434. group.each([&cnt](auto...) { ++cnt; });
  435. ASSERT_TRUE(registry.owned<int>());
  436. ASSERT_FALSE(registry.owned<char>());
  437. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  438. }
  439. TEST(Registry, PartialOwningGroupInitOnAssign) {
  440. entt::registry registry;
  441. auto group = registry.group<int>(entt::get<char>);
  442. const auto e0 = registry.create();
  443. registry.assign<int>(e0, 0);
  444. registry.assign<char>(e0, 'c');
  445. const auto e1 = registry.create();
  446. registry.assign<int>(e1, 0);
  447. const auto e2 = registry.create();
  448. registry.assign<int>(e2, 0);
  449. registry.assign<char>(e2, 'c');
  450. ASSERT_TRUE(registry.owned<int>());
  451. ASSERT_FALSE(registry.owned<char>());
  452. decltype(group)::size_type cnt{0};
  453. group.each([&cnt](auto...) { ++cnt; });
  454. ASSERT_TRUE(registry.owned<int>());
  455. ASSERT_FALSE(registry.owned<char>());
  456. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  457. }
  458. TEST(Registry, CleanViewAfterReset) {
  459. entt::registry registry;
  460. auto view = registry.view<int, char>();
  461. const auto entity = registry.create();
  462. registry.assign<int>(entity, 0);
  463. registry.assign<char>(entity, 'c');
  464. ASSERT_EQ(view.size(), entt::registry::size_type{1});
  465. registry.reset<char>(entity);
  466. ASSERT_EQ(view.size(), entt::registry::size_type{0});
  467. registry.assign<char>(entity, 'c');
  468. ASSERT_EQ(view.size(), entt::registry::size_type{1});
  469. registry.reset<int>();
  470. ASSERT_EQ(view.size(), entt::registry::size_type{0});
  471. registry.assign<int>(entity, 0);
  472. ASSERT_EQ(view.size(), entt::registry::size_type{1});
  473. registry.reset();
  474. ASSERT_EQ(view.size(), entt::registry::size_type{0});
  475. }
  476. TEST(Registry, CleanNonOwningGroupViewAfterReset) {
  477. entt::registry registry;
  478. auto group = registry.group<>(entt::get<int, char>);
  479. const auto entity = registry.create();
  480. registry.assign<int>(entity, 0);
  481. registry.assign<char>(entity, 'c');
  482. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  483. registry.reset<char>(entity);
  484. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  485. registry.assign<char>(entity, 'c');
  486. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  487. registry.reset<int>();
  488. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  489. registry.assign<int>(entity, 0);
  490. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  491. registry.reset();
  492. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  493. }
  494. TEST(Registry, CleanFullOwningGroupViewAfterReset) {
  495. entt::registry registry;
  496. auto group = registry.group<int, char>();
  497. const auto entity = registry.create();
  498. registry.assign<int>(entity, 0);
  499. registry.assign<char>(entity, 'c');
  500. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  501. registry.reset<char>(entity);
  502. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  503. registry.assign<char>(entity, 'c');
  504. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  505. registry.reset<int>();
  506. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  507. registry.assign<int>(entity, 0);
  508. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  509. registry.reset();
  510. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  511. }
  512. TEST(Registry, CleanPartialOwningGroupViewAfterReset) {
  513. entt::registry registry;
  514. auto group = registry.group<int>(entt::get<char>);
  515. const auto entity = registry.create();
  516. registry.assign<int>(entity, 0);
  517. registry.assign<char>(entity, 'c');
  518. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  519. registry.reset<char>(entity);
  520. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  521. registry.assign<char>(entity, 'c');
  522. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  523. registry.reset<int>();
  524. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  525. registry.assign<int>(entity, 0);
  526. ASSERT_EQ(group.size(), entt::registry::size_type{1});
  527. registry.reset();
  528. ASSERT_EQ(group.size(), entt::registry::size_type{0});
  529. }
  530. TEST(Registry, SortSingle) {
  531. entt::registry registry;
  532. int val = 0;
  533. registry.assign<int>(registry.create(), val++);
  534. registry.assign<int>(registry.create(), val++);
  535. registry.assign<int>(registry.create(), val++);
  536. for(auto entity: registry.view<int>()) {
  537. ASSERT_EQ(registry.get<int>(entity), --val);
  538. }
  539. registry.sort<int>(std::less<int>{});
  540. for(auto entity: registry.view<int>()) {
  541. ASSERT_EQ(registry.get<int>(entity), val++);
  542. }
  543. }
  544. TEST(Registry, SortMulti) {
  545. entt::registry registry;
  546. unsigned int uval = 0u;
  547. int ival = 0;
  548. for(auto i = 0; i < 3; ++i) {
  549. const auto entity = registry.create();
  550. registry.assign<unsigned int>(entity, uval++);
  551. registry.assign<int>(entity, ival++);
  552. }
  553. for(auto entity: registry.view<unsigned int>()) {
  554. ASSERT_EQ(registry.get<unsigned int>(entity), --uval);
  555. }
  556. for(auto entity: registry.view<int>()) {
  557. ASSERT_EQ(registry.get<int>(entity), --ival);
  558. }
  559. registry.sort<unsigned int>(std::less<unsigned int>{});
  560. registry.sort<int, unsigned int>();
  561. for(auto entity: registry.view<unsigned int>()) {
  562. ASSERT_EQ(registry.get<unsigned int>(entity), uval++);
  563. }
  564. for(auto entity: registry.view<int>()) {
  565. ASSERT_EQ(registry.get<int>(entity), ival++);
  566. }
  567. }
  568. TEST(Registry, ComponentsWithTypesFromStandardTemplateLibrary) {
  569. // see #37 - the test shouldn't crash, that's all
  570. entt::registry registry;
  571. const auto entity = registry.create();
  572. registry.assign<std::unordered_set<int>>(entity).insert(42);
  573. registry.destroy(entity);
  574. }
  575. TEST(Registry, ConstructWithComponents) {
  576. // it should compile, that's all
  577. entt::registry registry;
  578. const auto value = 0;
  579. registry.assign<int>(registry.create(), value);
  580. }
  581. TEST(Registry, MergeTwoRegistries) {
  582. entt::registry src;
  583. entt::registry dst;
  584. std::unordered_map<entt::entity, entt::entity> ref;
  585. auto merge = [&ref, &dst](const auto &view) {
  586. view.each([&](auto entity, const auto &component) {
  587. if(ref.find(entity) == ref.cend()) {
  588. const auto other = dst.create();
  589. dst.template assign<std::decay_t<decltype(component)>>(other, component);
  590. ref.emplace(entity, other);
  591. } else {
  592. using component_type = std::decay_t<decltype(component)>;
  593. dst.template assign<component_type>(ref[entity], component);
  594. }
  595. });
  596. };
  597. auto e0 = src.create();
  598. src.assign<int>(e0);
  599. src.assign<float>(e0);
  600. src.assign<double>(e0);
  601. auto e1 = src.create();
  602. src.assign<char>(e1);
  603. src.assign<float>(e1);
  604. src.assign<int>(e1);
  605. auto e2 = dst.create();
  606. dst.assign<int>(e2);
  607. dst.assign<char>(e2);
  608. dst.assign<double>(e2);
  609. auto e3 = dst.create();
  610. dst.assign<float>(e3);
  611. dst.assign<int>(e3);
  612. auto eq = [](auto begin, auto end) { ASSERT_EQ(begin, end); };
  613. auto ne = [](auto begin, auto end) { ASSERT_NE(begin, end); };
  614. eq(dst.view<int, float, double>().begin(), dst.view<int, float, double>().end());
  615. eq(dst.view<char, float, int>().begin(), dst.view<char, float, int>().end());
  616. merge(src.view<int>());
  617. merge(src.view<char>());
  618. merge(src.view<double>());
  619. merge(src.view<float>());
  620. ne(dst.view<int, float, double>().begin(), dst.view<int, float, double>().end());
  621. ne(dst.view<char, float, int>().begin(), dst.view<char, float, int>().end());
  622. }
  623. TEST(Registry, Signals) {
  624. entt::registry registry;
  625. listener listener;
  626. registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
  627. registry.on_destroy<int>().connect<&listener::decr<int>>(&listener);
  628. auto e0 = registry.create();
  629. auto e1 = registry.create();
  630. registry.assign<int>(e0);
  631. registry.assign<int>(e1);
  632. ASSERT_EQ(listener.counter, 2);
  633. ASSERT_EQ(listener.last, e1);
  634. registry.remove<int>(e0);
  635. ASSERT_EQ(listener.counter, 1);
  636. ASSERT_EQ(listener.last, e0);
  637. registry.on_destroy<int>().disconnect<&listener::decr<int>>(&listener);
  638. registry.remove<int>(e1);
  639. ASSERT_EQ(listener.counter, 1);
  640. ASSERT_EQ(listener.last, e0);
  641. registry.on_construct<int>().disconnect<&listener::incr<int>>(&listener);
  642. registry.assign<int>(e1);
  643. ASSERT_EQ(listener.counter, 1);
  644. ASSERT_EQ(listener.last, e0);
  645. registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
  646. registry.on_destroy<int>().connect<&listener::decr<int>>(&listener);
  647. registry.assign<int>(e0);
  648. registry.reset<int>(e1);
  649. ASSERT_EQ(listener.counter, 1);
  650. ASSERT_EQ(listener.last, e1);
  651. registry.reset<int>();
  652. ASSERT_EQ(listener.counter, 0);
  653. ASSERT_EQ(listener.last, e0);
  654. registry.assign<int>(e0);
  655. registry.assign<int>(e1);
  656. registry.destroy(e1);
  657. ASSERT_EQ(listener.counter, 1);
  658. ASSERT_EQ(listener.last, e1);
  659. registry.remove<int>(e0);
  660. registry.assign_or_replace<int>(e0);
  661. ASSERT_EQ(listener.counter, 1);
  662. ASSERT_EQ(listener.last, e0);
  663. registry.on_destroy<int>().disconnect<&listener::decr<int>>(&listener);
  664. registry.assign_or_replace<int>(e0);
  665. ASSERT_EQ(listener.counter, 1);
  666. ASSERT_EQ(listener.last, e0);
  667. registry.on_replace<int>().connect<&listener::incr<int>>(&listener);
  668. registry.assign_or_replace<int>(e0);
  669. ASSERT_EQ(listener.counter, 2);
  670. ASSERT_EQ(listener.last, e0);
  671. registry.replace<int>(e0);
  672. ASSERT_EQ(listener.counter, 3);
  673. ASSERT_EQ(listener.last, e0);
  674. }
  675. TEST(Registry, DestroyByComponents) {
  676. entt::registry registry;
  677. const auto e0 = registry.create();
  678. const auto e1 = registry.create();
  679. const auto e2 = registry.create();
  680. registry.assign<int>(e0);
  681. registry.assign<char>(e0);
  682. registry.assign<double>(e0);
  683. registry.assign<int>(e1);
  684. registry.assign<char>(e1);
  685. registry.assign<int>(e2);
  686. ASSERT_TRUE(registry.valid(e0));
  687. ASSERT_TRUE(registry.valid(e1));
  688. ASSERT_TRUE(registry.valid(e2));
  689. {
  690. const auto view = registry.view<int, char, double>();
  691. registry.destroy(view.begin(), view.end());
  692. }
  693. ASSERT_FALSE(registry.valid(e0));
  694. ASSERT_TRUE(registry.valid(e1));
  695. ASSERT_TRUE(registry.valid(e2));
  696. {
  697. const auto view = registry.view<int, char>();
  698. registry.destroy(view.begin(), view.end());
  699. }
  700. ASSERT_FALSE(registry.valid(e0));
  701. ASSERT_FALSE(registry.valid(e1));
  702. ASSERT_TRUE(registry.valid(e2));
  703. {
  704. const auto view = registry.view<int>();
  705. registry.destroy(view.begin(), view.end());
  706. }
  707. ASSERT_FALSE(registry.valid(e0));
  708. ASSERT_FALSE(registry.valid(e1));
  709. ASSERT_FALSE(registry.valid(e2));
  710. }
  711. TEST(Registry, CreateManyEntitiesAtOnce) {
  712. entt::registry registry;
  713. entt::entity entities[3];
  714. const auto entity = registry.create();
  715. registry.destroy(registry.create());
  716. registry.destroy(entity);
  717. registry.destroy(registry.create());
  718. registry.create(std::begin(entities), std::end(entities));
  719. ASSERT_TRUE(registry.valid(entities[0]));
  720. ASSERT_TRUE(registry.valid(entities[1]));
  721. ASSERT_TRUE(registry.valid(entities[2]));
  722. ASSERT_EQ(registry.entity(entities[0]), entt::entity{0});
  723. ASSERT_EQ(registry.version(entities[0]), entt::registry::version_type{2});
  724. ASSERT_EQ(registry.entity(entities[1]), entt::entity{1});
  725. ASSERT_EQ(registry.version(entities[1]), entt::registry::version_type{1});
  726. ASSERT_EQ(registry.entity(entities[2]), entt::entity{2});
  727. ASSERT_EQ(registry.version(entities[2]), entt::registry::version_type{0});
  728. }
  729. TEST(Registry, CreateAnEntityWithComponents) {
  730. entt::registry registry;
  731. const auto &[entity, ivalue, cvalue] = registry.create<int, char>();
  732. ASSERT_FALSE(registry.empty<int>());
  733. ASSERT_FALSE(registry.empty<char>());
  734. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{1});
  735. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{1});
  736. ASSERT_TRUE((registry.has<int, char>(entity)));
  737. ivalue = 42;
  738. cvalue = 'c';
  739. ASSERT_EQ(registry.get<int>(entity), 42);
  740. ASSERT_EQ(registry.get<char>(entity), 'c');
  741. }
  742. TEST(Registry, CreateManyEntitiesWithComponentsAtOnce) {
  743. entt::registry registry;
  744. entt::entity entities[3];
  745. const auto entity = registry.create();
  746. registry.destroy(registry.create());
  747. registry.destroy(entity);
  748. registry.destroy(registry.create());
  749. const auto [iptr, cptr] = registry.create<int, char>(std::begin(entities), std::end(entities));
  750. ASSERT_FALSE(registry.empty<int>());
  751. ASSERT_FALSE(registry.empty<char>());
  752. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{3});
  753. ASSERT_EQ(registry.size<int>(), entt::registry::size_type{3});
  754. ASSERT_TRUE(registry.valid(entities[0]));
  755. ASSERT_TRUE(registry.valid(entities[1]));
  756. ASSERT_TRUE(registry.valid(entities[2]));
  757. ASSERT_EQ(registry.entity(entities[0]), entt::entity{0});
  758. ASSERT_EQ(registry.version(entities[0]), entt::registry::version_type{2});
  759. ASSERT_EQ(registry.entity(entities[1]), entt::entity{1});
  760. ASSERT_EQ(registry.version(entities[1]), entt::registry::version_type{1});
  761. ASSERT_EQ(registry.entity(entities[2]), entt::entity{2});
  762. ASSERT_EQ(registry.version(entities[2]), entt::registry::version_type{0});
  763. ASSERT_TRUE((registry.has<int, char>(entities[0])));
  764. ASSERT_TRUE((registry.has<int, char>(entities[1])));
  765. ASSERT_TRUE((registry.has<int, char>(entities[2])));
  766. for(auto i = 0; i < 3; ++i) {
  767. iptr[i] = i;
  768. cptr[i] = char('a'+i);
  769. }
  770. for(auto i = 0; i < 3; ++i) {
  771. ASSERT_EQ(registry.get<int>(entities[i]), i);
  772. ASSERT_EQ(registry.get<char>(entities[i]), char('a'+i));
  773. }
  774. }
  775. TEST(Registry, CreateManyEntitiesWithComponentsAtOnceWithListener) {
  776. entt::registry registry;
  777. entt::entity entities[3];
  778. listener listener;
  779. registry.on_construct<int>().connect<&listener::incr<int>>(&listener);
  780. registry.create<int, char>(std::begin(entities), std::end(entities));
  781. ASSERT_EQ(listener.counter, 3);
  782. }
  783. TEST(Registry, NonOwningGroupInterleaved) {
  784. entt::registry registry;
  785. typename entt::entity entity = entt::null;
  786. entity = registry.create();
  787. registry.assign<int>(entity);
  788. registry.assign<char>(entity);
  789. const auto group = registry.group<>(entt::get<int, char>);
  790. entity = registry.create();
  791. registry.assign<int>(entity);
  792. registry.assign<char>(entity);
  793. decltype(group)::size_type cnt{0};
  794. group.each([&cnt](auto...) { ++cnt; });
  795. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  796. }
  797. TEST(Registry, FullOwningGroupInterleaved) {
  798. entt::registry registry;
  799. typename entt::entity entity = entt::null;
  800. entity = registry.create();
  801. registry.assign<int>(entity);
  802. registry.assign<char>(entity);
  803. const auto group = registry.group<int, char>();
  804. entity = registry.create();
  805. registry.assign<int>(entity);
  806. registry.assign<char>(entity);
  807. decltype(group)::size_type cnt{0};
  808. group.each([&cnt](auto...) { ++cnt; });
  809. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  810. }
  811. TEST(Registry, PartialOwningGroupInterleaved) {
  812. entt::registry registry;
  813. typename entt::entity entity = entt::null;
  814. entity = registry.create();
  815. registry.assign<int>(entity);
  816. registry.assign<char>(entity);
  817. const auto group = registry.group<int>(entt::get<char>);
  818. entity = registry.create();
  819. registry.assign<int>(entity);
  820. registry.assign<char>(entity);
  821. decltype(group)::size_type cnt{0};
  822. group.each([&cnt](auto...) { ++cnt; });
  823. ASSERT_EQ(cnt, decltype(group)::size_type{2});
  824. }
  825. TEST(Registry, NonOwningGroupSortInterleaved) {
  826. entt::registry registry;
  827. const auto group = registry.group<>(entt::get<int, char>);
  828. const auto e0 = registry.create();
  829. registry.assign<int>(e0, 0);
  830. registry.assign<char>(e0, '0');
  831. const auto e1 = registry.create();
  832. registry.assign<int>(e1, 1);
  833. registry.assign<char>(e1, '1');
  834. registry.sort<int>([](auto lhs, auto rhs) { return lhs > rhs; });
  835. registry.sort<char>([](auto lhs, auto rhs) { return lhs < rhs; });
  836. const auto e2 = registry.create();
  837. registry.assign<int>(e2, 2);
  838. registry.assign<char>(e2, '2');
  839. group.each([e0, e1, e2](const auto entity, const auto &i, const auto &c) {
  840. if(entity == e0) {
  841. ASSERT_EQ(i, 0);
  842. ASSERT_EQ(c, '0');
  843. } else if(entity == e1) {
  844. ASSERT_EQ(i, 1);
  845. ASSERT_EQ(c, '1');
  846. } else if(entity == e2) {
  847. ASSERT_EQ(i, 2);
  848. ASSERT_EQ(c, '2');
  849. }
  850. });
  851. }
  852. TEST(Registry, Clone) {
  853. entt::registry registry;
  854. entt::registry other;
  855. registry.destroy(registry.create());
  856. const auto e0 = registry.create();
  857. registry.assign<int>(e0, 0);
  858. registry.assign<double>(e0, 0.0);
  859. const auto e1 = registry.create();
  860. registry.assign<int>(e1, 1);
  861. registry.assign<char>(e1, '1');
  862. registry.assign<double>(e1, 1.1);
  863. const auto e2 = registry.create();
  864. registry.assign<int>(e2, 2);
  865. registry.assign<char>(e2, '2');
  866. registry.destroy(e1);
  867. other = registry.clone<int, char>();
  868. ASSERT_EQ(other.size(), registry.size());
  869. ASSERT_EQ(other.alive(), registry.alive());
  870. ASSERT_TRUE(other.valid(e0));
  871. ASSERT_FALSE(other.valid(e1));
  872. ASSERT_TRUE(other.valid(e2));
  873. ASSERT_TRUE((other.has<int>(e0)));
  874. ASSERT_FALSE((other.has<double>(e0)));
  875. ASSERT_TRUE((other.has<int, char>(e2)));
  876. ASSERT_EQ(other.get<int>(e0), 0);
  877. ASSERT_EQ(other.get<int>(e2), 2);
  878. ASSERT_EQ(other.get<char>(e2), '2');
  879. other = registry.clone();
  880. ASSERT_EQ(other.size(), registry.size());
  881. ASSERT_EQ(other.alive(), registry.alive());
  882. ASSERT_TRUE(other.valid(e0));
  883. ASSERT_FALSE(other.valid(e1));
  884. ASSERT_TRUE(other.valid(e2));
  885. ASSERT_TRUE((other.has<int, double>(e0)));
  886. ASSERT_TRUE((other.has<int, char>(e2)));
  887. ASSERT_EQ(other.get<int>(e0), 0);
  888. ASSERT_EQ(other.get<double>(e0), 0.);
  889. ASSERT_EQ(other.get<int>(e2), 2);
  890. ASSERT_EQ(other.get<char>(e2), '2');
  891. other = registry.clone<char>();
  892. ASSERT_EQ(other.size(), registry.size());
  893. ASSERT_EQ(other.alive(), registry.alive());
  894. ASSERT_TRUE(other.valid(e0));
  895. ASSERT_FALSE(other.valid(e1));
  896. ASSERT_TRUE(other.valid(e2));
  897. ASSERT_FALSE((other.has<int>(e0)));
  898. ASSERT_FALSE((other.has<double>(e0)));
  899. ASSERT_FALSE((other.has<int>(e2)));
  900. ASSERT_TRUE((other.has<char>(e2)));
  901. ASSERT_TRUE(other.orphan(e0));
  902. ASSERT_EQ(other.get<char>(e2), '2');
  903. const auto entity = registry.create();
  904. listener listener;
  905. ASSERT_NE(e1, entity);
  906. ASSERT_EQ(registry.entity(e1), registry.entity(entity));
  907. registry.on_construct<char>().connect<&listener::incr<char>>(&listener);
  908. registry.on_destroy<char>().connect<&listener::decr<char>>(&listener);
  909. registry.assign<char>(entity, 'e');
  910. registry.assign<char>(e0, '0');
  911. registry.remove<char>(e0);
  912. ASSERT_EQ(listener.counter, 1);
  913. ASSERT_EQ(listener.last, e0);
  914. }
  915. TEST(Registry, GetOrAssign) {
  916. entt::registry registry;
  917. const auto entity = registry.create();
  918. const auto value = registry.get_or_assign<int>(entity, 3);
  919. ASSERT_TRUE(registry.has<int>(entity));
  920. ASSERT_EQ(registry.get<int>(entity), value);
  921. ASSERT_EQ(registry.get<int>(entity), 3);
  922. }
  923. TEST(Registry, Constness) {
  924. entt::registry registry;
  925. ASSERT_TRUE((std::is_same_v<decltype(registry.get<int>({})), int &>));
  926. ASSERT_TRUE((std::is_same_v<decltype(registry.get<int, char>({})), std::tuple<int &, char &>>));
  927. ASSERT_TRUE((std::is_same_v<decltype(registry.try_get<int>({})), int *>));
  928. ASSERT_TRUE((std::is_same_v<decltype(registry.try_get<int, char>({})), std::tuple<int *, char *>>));
  929. ASSERT_TRUE((std::is_same_v<decltype(std::as_const(registry).get<int>({})), const int &>));
  930. ASSERT_TRUE((std::is_same_v<decltype(std::as_const(registry).get<int, char>({})), std::tuple<const int &, const char &>>));
  931. ASSERT_TRUE((std::is_same_v<decltype(std::as_const(registry).try_get<int>({})), const int *>));
  932. ASSERT_TRUE((std::is_same_v<decltype(std::as_const(registry).try_get<int, char>({})), std::tuple<const int *, const char *>>));
  933. }
  934. TEST(Registry, BatchCreateAmbiguousCall) {
  935. struct ambiguous { std::uint32_t foo; std::uint64_t bar; };
  936. entt::registry registry;
  937. const auto entity = registry.create();
  938. std::uint32_t foo = 32u;
  939. std::uint64_t bar = 64u;
  940. // this should work, no other tests required
  941. registry.assign<ambiguous>(entity, foo, bar);
  942. }