registry.cpp 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507
  1. #include <array>
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <functional>
  5. #include <iterator>
  6. #include <memory>
  7. #include <tuple>
  8. #include <unordered_set>
  9. #include <utility>
  10. #include <vector>
  11. #include <gtest/gtest.h>
  12. #include <entt/config/config.h>
  13. #include <entt/core/hashed_string.hpp>
  14. #include <entt/core/type_info.hpp>
  15. #include <entt/entity/entity.hpp>
  16. #include <entt/entity/registry.hpp>
  17. #include <entt/entity/view.hpp>
  18. #include "../../common/aggregate.h"
  19. #include "../../common/config.h"
  20. #include "../../common/empty.h"
  21. #include "../../common/entity.h"
  22. #include "../../common/mixin.hpp"
  23. #include "../../common/non_default_constructible.h"
  24. #include "../../common/pointer_stable.h"
  25. struct no_eto_type {
  26. static constexpr std::size_t page_size = 1024u;
  27. };
  28. bool operator==(const no_eto_type &lhs, const no_eto_type &rhs) {
  29. return &lhs == &rhs;
  30. }
  31. struct listener {
  32. template<typename Type>
  33. static void sort(entt::registry &registry) {
  34. registry.sort<Type>([](auto lhs, auto rhs) { return lhs < rhs; });
  35. }
  36. void incr(const entt::registry &, entt::entity entity) {
  37. last = entity;
  38. ++counter;
  39. }
  40. void decr(const entt::registry &, entt::entity entity) {
  41. last = entity;
  42. --counter;
  43. }
  44. entt::entity last{entt::null};
  45. int counter{0};
  46. };
  47. struct owner {
  48. void receive(const entt::registry &ref) {
  49. parent = &ref;
  50. }
  51. const entt::registry *parent{nullptr};
  52. };
  53. struct destruction_order {
  54. using ctx_check_type = int;
  55. destruction_order(const entt::registry &ref, bool &ctx)
  56. : registry{&ref},
  57. ctx_check{&ctx} {
  58. *ctx_check = (registry->ctx().find<ctx_check_type>() != nullptr);
  59. }
  60. destruction_order(const destruction_order &) = delete;
  61. destruction_order &operator=(const destruction_order &) = delete;
  62. ~destruction_order() {
  63. *ctx_check = *ctx_check && (registry->ctx().find<ctx_check_type>() != nullptr);
  64. }
  65. private:
  66. const entt::registry *registry;
  67. bool *ctx_check{};
  68. };
  69. struct entity_traits {
  70. using value_type = test::entity;
  71. using entity_type = uint32_t;
  72. using version_type = uint16_t;
  73. static constexpr entity_type entity_mask = 0xFF;
  74. static constexpr entity_type version_mask = 0x00;
  75. };
  76. template<>
  77. struct entt::entt_traits<test::entity>: entt::basic_entt_traits<entity_traits> {
  78. static constexpr auto page_size = ENTT_SPARSE_PAGE;
  79. };
  80. TEST(Registry, Functionalities) {
  81. using traits_type = entt::entt_traits<entt::entity>;
  82. entt::registry registry{};
  83. ASSERT_NO_THROW([[maybe_unused]] auto alloc = registry.get_allocator());
  84. ASSERT_EQ(registry.storage<entt::entity>().size(), 0u);
  85. ASSERT_EQ(registry.storage<entt::entity>().free_list(), 0u);
  86. ASSERT_NO_THROW(registry.storage<entt::entity>().reserve(4));
  87. ASSERT_EQ(registry.storage<entt::entity>().capacity(), 4u);
  88. ASSERT_TRUE(registry.storage<entt::entity>().empty());
  89. ASSERT_EQ(registry.storage<int>().size(), 0u);
  90. ASSERT_EQ(registry.storage<char>().size(), 0u);
  91. ASSERT_TRUE(registry.storage<int>().empty());
  92. ASSERT_TRUE(registry.storage<char>().empty());
  93. const auto e0 = registry.create();
  94. const auto e1 = registry.create();
  95. registry.emplace<int>(e1);
  96. registry.emplace<char>(e1);
  97. ASSERT_TRUE(registry.all_of<>(e0));
  98. ASSERT_FALSE(registry.any_of<>(e1));
  99. ASSERT_EQ(registry.storage<int>().size(), 1u);
  100. ASSERT_EQ(registry.storage<char>().size(), 1u);
  101. ASSERT_FALSE(registry.storage<int>().empty());
  102. ASSERT_FALSE(registry.storage<char>().empty());
  103. ASSERT_NE(e0, e1);
  104. ASSERT_FALSE((registry.all_of<int, const char>(e0)));
  105. ASSERT_TRUE((registry.all_of<const int, char>(e1)));
  106. ASSERT_FALSE((registry.any_of<int, const double>(e0)));
  107. ASSERT_TRUE((registry.any_of<const int, double>(e1)));
  108. ASSERT_EQ(registry.try_get<int>(e0), nullptr);
  109. ASSERT_NE(registry.try_get<int>(e1), nullptr);
  110. ASSERT_EQ(registry.try_get<char>(e0), nullptr);
  111. ASSERT_NE(registry.try_get<char>(e1), nullptr);
  112. ASSERT_EQ(registry.try_get<double>(e0), nullptr);
  113. ASSERT_EQ(registry.try_get<double>(e1), nullptr);
  114. ASSERT_EQ(registry.emplace<int>(e0, 4), 4);
  115. ASSERT_EQ(registry.emplace<char>(e0, 'c'), 'c');
  116. ASSERT_NO_THROW(registry.erase<int>(e1));
  117. ASSERT_NO_THROW(registry.erase<char>(e1));
  118. ASSERT_TRUE((registry.all_of<const int, char>(e0)));
  119. ASSERT_FALSE((registry.all_of<int, const char>(e1)));
  120. ASSERT_TRUE((registry.any_of<const int, double>(e0)));
  121. ASSERT_FALSE((registry.any_of<int, const double>(e1)));
  122. const auto e2 = registry.create();
  123. registry.emplace_or_replace<int>(e2, registry.get<int>(e0));
  124. registry.emplace_or_replace<char>(e2, registry.get<char>(e0));
  125. ASSERT_TRUE((registry.all_of<int, char>(e2)));
  126. ASSERT_EQ(registry.get<int>(e0), 4);
  127. ASSERT_EQ(registry.get<char>(e0), 'c');
  128. ASSERT_NE(registry.try_get<int>(e0), nullptr);
  129. ASSERT_NE(registry.try_get<char>(e0), nullptr);
  130. ASSERT_EQ(registry.try_get<double>(e0), nullptr);
  131. ASSERT_EQ(*registry.try_get<int>(e0), 4);
  132. ASSERT_EQ(*registry.try_get<char>(e0), 'c');
  133. ASSERT_EQ(std::get<0>(registry.get<int, char>(e0)), 4);
  134. ASSERT_EQ(*std::get<0>(registry.try_get<int, char, double>(e0)), 4);
  135. ASSERT_EQ(std::get<1>(static_cast<const entt::registry &>(registry).get<int, char>(e0)), 'c');
  136. ASSERT_EQ(*std::get<1>(static_cast<const entt::registry &>(registry).try_get<int, char, double>(e0)), 'c');
  137. ASSERT_EQ(registry.get<int>(e0), registry.get<int>(e2));
  138. ASSERT_EQ(registry.get<char>(e0), registry.get<char>(e2));
  139. ASSERT_NE(&registry.get<int>(e0), &registry.get<int>(e2));
  140. ASSERT_NE(&registry.get<char>(e0), &registry.get<char>(e2));
  141. ASSERT_EQ(registry.patch<int>(e0, [](auto &instance) { instance = 2; }), 2);
  142. ASSERT_EQ(registry.replace<int>(e0, 3), 3);
  143. ASSERT_NO_THROW(registry.emplace_or_replace<int>(e0, 1));
  144. ASSERT_NO_THROW(registry.emplace_or_replace<int>(e1, 1));
  145. ASSERT_EQ(static_cast<const entt::registry &>(registry).get<int>(e0), 1);
  146. ASSERT_EQ(static_cast<const entt::registry &>(registry).get<int>(e1), 1);
  147. ASSERT_EQ(registry.storage<entt::entity>().size(), 3u);
  148. ASSERT_EQ(registry.storage<entt::entity>().free_list(), 3u);
  149. ASSERT_EQ(traits_type::to_version(e2), 0u);
  150. ASSERT_EQ(registry.current(e2), 0u);
  151. ASSERT_NO_THROW(registry.destroy(e2));
  152. ASSERT_EQ(traits_type::to_version(e2), 0u);
  153. ASSERT_EQ(registry.current(e2), 1u);
  154. ASSERT_TRUE(registry.valid(e0));
  155. ASSERT_TRUE(registry.valid(e1));
  156. ASSERT_FALSE(registry.valid(e2));
  157. ASSERT_EQ(registry.storage<entt::entity>().size(), 3u);
  158. ASSERT_EQ(registry.storage<entt::entity>().free_list(), 2u);
  159. ASSERT_NO_THROW(registry.clear());
  160. ASSERT_EQ(registry.storage<entt::entity>().size(), 3u);
  161. ASSERT_EQ(registry.storage<entt::entity>().free_list(), 0u);
  162. ASSERT_FALSE(registry.storage<entt::entity>().empty());
  163. const auto e3 = registry.create();
  164. ASSERT_EQ(registry.get_or_emplace<int>(e3, 3), 3);
  165. ASSERT_EQ(registry.get_or_emplace<char>(e3, 'c'), 'c');
  166. ASSERT_EQ(registry.storage<int>().size(), 1u);
  167. ASSERT_EQ(registry.storage<char>().size(), 1u);
  168. ASSERT_FALSE(registry.storage<int>().empty());
  169. ASSERT_FALSE(registry.storage<char>().empty());
  170. ASSERT_TRUE((registry.all_of<int, char>(e3)));
  171. ASSERT_EQ(registry.get<int>(e3), 3);
  172. ASSERT_EQ(registry.get<char>(e3), 'c');
  173. ASSERT_NO_THROW(registry.clear<int>());
  174. ASSERT_EQ(registry.storage<int>().size(), 0u);
  175. ASSERT_EQ(registry.storage<char>().size(), 1u);
  176. ASSERT_TRUE(registry.storage<int>().empty());
  177. ASSERT_FALSE(registry.storage<char>().empty());
  178. ASSERT_NO_THROW(registry.clear());
  179. ASSERT_EQ(registry.storage<int>().size(), 0u);
  180. ASSERT_EQ(registry.storage<char>().size(), 0u);
  181. ASSERT_TRUE(registry.storage<int>().empty());
  182. ASSERT_TRUE(registry.storage<char>().empty());
  183. const auto e4 = registry.create();
  184. const auto e5 = registry.create();
  185. registry.emplace<int>(e4);
  186. ASSERT_EQ(registry.remove<int>(e4), 1u);
  187. ASSERT_EQ(registry.remove<int>(e5), 0u);
  188. ASSERT_EQ(registry.storage<int>().size(), 0u);
  189. ASSERT_EQ(registry.storage<char>().size(), 0u);
  190. ASSERT_TRUE(registry.storage<int>().empty());
  191. }
  192. TEST(Registry, Constructors) {
  193. entt::registry registry{};
  194. entt::registry other{64u};
  195. ASSERT_TRUE(registry.storage<entt::entity>().empty());
  196. ASSERT_NO_THROW([[maybe_unused]] auto alloc = registry.get_allocator());
  197. ASSERT_EQ(registry.storage().begin(), registry.storage().end());
  198. ASSERT_TRUE(other.storage<entt::entity>().empty());
  199. ASSERT_NO_THROW([[maybe_unused]] auto alloc = other.get_allocator());
  200. ASSERT_EQ(other.storage().begin(), other.storage().end());
  201. }
  202. TEST(Registry, Move) {
  203. entt::registry registry{};
  204. const auto entity = registry.create();
  205. owner test{};
  206. registry.on_construct<int>().connect<&owner::receive>(test);
  207. registry.on_destroy<int>().connect<&owner::receive>(test);
  208. ASSERT_EQ(test.parent, nullptr);
  209. registry.emplace<int>(entity);
  210. ASSERT_EQ(test.parent, &registry);
  211. entt::registry other{std::move(registry)};
  212. other.erase<int>(entity);
  213. registry = {};
  214. registry.emplace<int>(registry.create(entity));
  215. ASSERT_EQ(test.parent, &other);
  216. registry = std::move(other);
  217. registry.emplace<int>(entity);
  218. registry.emplace<int>(registry.create(entity));
  219. ASSERT_EQ(test.parent, &registry);
  220. }
  221. TEST(Registry, Swap) {
  222. entt::registry registry{};
  223. const auto entity = registry.create();
  224. owner test{};
  225. registry.on_construct<int>().connect<&owner::receive>(test);
  226. registry.on_destroy<int>().connect<&owner::receive>(test);
  227. ASSERT_EQ(test.parent, nullptr);
  228. registry.emplace<int>(entity);
  229. ASSERT_EQ(test.parent, &registry);
  230. entt::registry other{};
  231. other.swap(registry);
  232. other.erase<int>(entity);
  233. registry = {};
  234. registry.emplace<int>(registry.create(entity));
  235. ASSERT_EQ(test.parent, &other);
  236. registry.swap(other);
  237. registry.emplace<int>(entity);
  238. registry.emplace<int>(registry.create(entity));
  239. ASSERT_EQ(test.parent, &registry);
  240. }
  241. TEST(Registry, StorageIterable) {
  242. using namespace entt::literals;
  243. entt::registry registry{};
  244. const auto entity = registry.create();
  245. auto &storage = registry.storage<int>("other"_hs);
  246. storage.emplace(entity);
  247. for(auto [id, pool]: registry.storage()) {
  248. testing::StaticAssertTypeEq<decltype(pool), entt::sparse_set &>();
  249. testing::StaticAssertTypeEq<decltype(id), entt::id_type>();
  250. ASSERT_TRUE(pool.contains(entity));
  251. ASSERT_EQ(&storage, &pool);
  252. ASSERT_EQ(id, "other"_hs);
  253. }
  254. }
  255. TEST(Registry, ConstStorageIterable) {
  256. using namespace entt::literals;
  257. entt::registry registry{};
  258. const auto entity = registry.create();
  259. auto &storage = registry.storage<int>("other"_hs);
  260. storage.emplace(entity);
  261. for(auto &&curr: std::as_const(registry).storage()) {
  262. testing::StaticAssertTypeEq<decltype(curr.second), const entt::sparse_set &>();
  263. testing::StaticAssertTypeEq<decltype(curr.first), entt::id_type>();
  264. ASSERT_TRUE(curr.second.contains(entity));
  265. ASSERT_EQ(&storage, &curr.second);
  266. ASSERT_EQ(curr.first, "other"_hs);
  267. }
  268. }
  269. TEST(Registry, RegistryStorageIterator) {
  270. entt::registry registry{};
  271. const auto entity = registry.create();
  272. registry.emplace<int>(entity);
  273. auto iterable = registry.storage();
  274. auto end{iterable.begin()};
  275. decltype(end) begin{};
  276. begin = iterable.end();
  277. std::swap(begin, end);
  278. ASSERT_EQ(begin, iterable.cbegin());
  279. ASSERT_EQ(end, iterable.cend());
  280. ASSERT_NE(begin, end);
  281. ASSERT_EQ(begin++, iterable.begin());
  282. ASSERT_EQ(begin--, iterable.end());
  283. ASSERT_EQ(begin + 1, iterable.end());
  284. ASSERT_EQ(end - 1, iterable.begin());
  285. ASSERT_EQ(++begin, iterable.end());
  286. ASSERT_EQ(--begin, iterable.begin());
  287. ASSERT_EQ(begin += 1, iterable.end());
  288. ASSERT_EQ(begin -= 1, iterable.begin());
  289. ASSERT_EQ(begin + (end - begin), iterable.end());
  290. ASSERT_EQ(begin - (begin - end), iterable.end());
  291. ASSERT_EQ(end - (end - begin), iterable.begin());
  292. ASSERT_EQ(end + (begin - end), iterable.begin());
  293. ASSERT_EQ(begin[0u].first, iterable.begin()->first);
  294. ASSERT_EQ(&begin[0u].second, &(*iterable.begin()).second);
  295. ASSERT_LT(begin, end);
  296. ASSERT_LE(begin, iterable.begin());
  297. ASSERT_GT(end, begin);
  298. ASSERT_GE(end, iterable.end());
  299. ASSERT_EQ(begin[0u].first, entt::type_id<int>().hash());
  300. ASSERT_TRUE(begin[0u].second.contains(entity));
  301. }
  302. TEST(Registry, RegistryConstStorageIterator) {
  303. entt::registry registry{};
  304. const auto entity = registry.create();
  305. registry.emplace<int>(entity);
  306. auto iterable = std::as_const(registry).storage();
  307. auto end{iterable.begin()};
  308. decltype(end) begin{};
  309. begin = iterable.end();
  310. std::swap(begin, end);
  311. ASSERT_EQ(begin, iterable.cbegin());
  312. ASSERT_EQ(end, iterable.cend());
  313. ASSERT_NE(begin, end);
  314. ASSERT_EQ(begin++, iterable.begin());
  315. ASSERT_EQ(begin--, iterable.end());
  316. ASSERT_EQ(begin + 1, iterable.end());
  317. ASSERT_EQ(end - 1, iterable.begin());
  318. ASSERT_EQ(++begin, iterable.end());
  319. ASSERT_EQ(--begin, iterable.begin());
  320. ASSERT_EQ(begin += 1, iterable.end());
  321. ASSERT_EQ(begin -= 1, iterable.begin());
  322. ASSERT_EQ(begin + (end - begin), iterable.end());
  323. ASSERT_EQ(begin - (begin - end), iterable.end());
  324. ASSERT_EQ(end - (end - begin), iterable.begin());
  325. ASSERT_EQ(end + (begin - end), iterable.begin());
  326. ASSERT_EQ(begin[0u].first, iterable.begin()->first);
  327. ASSERT_EQ(&begin[0u].second, &(*iterable.begin()).second);
  328. ASSERT_LT(begin, end);
  329. ASSERT_LE(begin, iterable.begin());
  330. ASSERT_GT(end, begin);
  331. ASSERT_GE(end, iterable.end());
  332. ASSERT_EQ(begin[0u].first, entt::type_id<int>().hash());
  333. ASSERT_TRUE(begin[0u].second.contains(entity));
  334. }
  335. TEST(Registry, RegistryStorageIteratorConversion) {
  336. entt::registry registry{};
  337. registry.storage<int>();
  338. auto proxy = registry.storage();
  339. [[maybe_unused]] auto cproxy = std::as_const(registry).storage();
  340. const typename decltype(proxy)::iterator it = proxy.begin();
  341. typename decltype(cproxy)::iterator cit = it;
  342. testing::StaticAssertTypeEq<decltype(*it), std::pair<entt::id_type, entt::sparse_set &>>();
  343. testing::StaticAssertTypeEq<decltype(*cit), std::pair<entt::id_type, const entt::sparse_set &>>();
  344. ASSERT_EQ(it->first, entt::type_id<int>().hash());
  345. ASSERT_EQ((*it).second.type(), entt::type_id<int>());
  346. ASSERT_EQ(it->first, cit->first);
  347. ASSERT_EQ((*it).second.type(), (*cit).second.type());
  348. ASSERT_EQ(it - cit, 0);
  349. ASSERT_EQ(cit - it, 0);
  350. ASSERT_LE(it, cit);
  351. ASSERT_LE(cit, it);
  352. ASSERT_GE(it, cit);
  353. ASSERT_GE(cit, it);
  354. ASSERT_EQ(it, cit);
  355. ASSERT_NE(++cit, it);
  356. }
  357. TEST(Registry, Storage) {
  358. using namespace entt::literals;
  359. entt::registry registry{};
  360. auto &storage = registry.storage<test::empty>("other"_hs);
  361. const auto entity = registry.create();
  362. testing::StaticAssertTypeEq<decltype(registry.storage<test::empty>()), entt::storage_type_t<test::empty> &>();
  363. testing::StaticAssertTypeEq<decltype(std::as_const(registry).storage<test::empty>()), const entt::storage_type_t<test::empty> *>();
  364. testing::StaticAssertTypeEq<decltype(registry.storage("other"_hs)), entt::storage_type_t<test::empty>::base_type *>();
  365. testing::StaticAssertTypeEq<decltype(std::as_const(registry).storage("other"_hs)), const entt::storage_type_t<test::empty>::base_type *>();
  366. ASSERT_NE(registry.storage("other"_hs), nullptr);
  367. ASSERT_EQ(std::as_const(registry).storage("rehto"_hs), nullptr);
  368. ASSERT_EQ(&registry.storage<test::empty>("other"_hs), &storage);
  369. ASSERT_NE(std::as_const(registry).storage<test::empty>(), &storage);
  370. ASSERT_FALSE(registry.any_of<test::empty>(entity));
  371. ASSERT_FALSE(storage.contains(entity));
  372. registry.emplace<test::empty>(entity);
  373. ASSERT_FALSE(storage.contains(entity));
  374. ASSERT_TRUE(registry.any_of<test::empty>(entity));
  375. ASSERT_EQ((entt::basic_view{registry.storage<test::empty>(), storage}.size_hint()), 0u);
  376. storage.emplace(entity);
  377. ASSERT_TRUE(storage.contains(entity));
  378. ASSERT_TRUE(registry.any_of<test::empty>(entity));
  379. ASSERT_EQ((entt::basic_view{registry.storage<test::empty>(), storage}.size_hint()), 1u);
  380. registry.destroy(entity);
  381. ASSERT_EQ(registry.create(entity), entity);
  382. ASSERT_FALSE(storage.contains(entity));
  383. ASSERT_FALSE(registry.any_of<test::empty>(entity));
  384. }
  385. ENTT_DEBUG_TEST(RegistryDeathTest, Storage) {
  386. using namespace entt::literals;
  387. entt::registry registry{};
  388. registry.storage<test::empty>("other"_hs);
  389. ASSERT_DEATH(registry.storage<int>("other"_hs), "");
  390. ASSERT_DEATH([[maybe_unused]] const auto *storage = std::as_const(registry).storage<int>("other"_hs), "");
  391. ASSERT_DEATH(registry.storage<entt::entity>("other"_hs), "");
  392. ASSERT_DEATH([[maybe_unused]] const auto *storage = std::as_const(registry).storage<entt::entity>("other"_hs), "");
  393. }
  394. TEST(Registry, StorageReset) {
  395. using namespace entt::literals;
  396. entt::registry registry{};
  397. registry.storage<int>();
  398. registry.storage<int>("other"_hs);
  399. ASSERT_NE(std::as_const(registry).storage<int>(), nullptr);
  400. ASSERT_NE(registry.storage("other"_hs), nullptr);
  401. ASSERT_EQ(registry.reset("other"_hs), 1u);
  402. ASSERT_NE(std::as_const(registry).storage<int>(), nullptr);
  403. ASSERT_EQ(registry.storage("other"_hs), nullptr);
  404. ASSERT_EQ(registry.reset("other"_hs), 0u);
  405. ASSERT_EQ(registry.reset(entt::type_id<int>().hash()), 1u);
  406. ASSERT_EQ(registry.reset(entt::type_id<int>().hash()), 0u);
  407. ASSERT_EQ(std::as_const(registry).storage<int>(), nullptr);
  408. ASSERT_EQ(registry.storage("other"_hs), nullptr);
  409. }
  410. ENTT_DEBUG_TEST(RegistryDeathTest, StorageReset) {
  411. entt::registry registry{};
  412. const entt::entity entity = registry.create();
  413. ASSERT_TRUE(registry.valid(entity));
  414. ASSERT_DEATH(registry.reset(entt::type_id<entt::entity>().hash()), "");
  415. ASSERT_TRUE(registry.valid(entity));
  416. }
  417. TEST(Registry, Identifiers) {
  418. using traits_type = entt::entt_traits<entt::entity>;
  419. entt::registry registry{};
  420. const auto pre = registry.create();
  421. ASSERT_EQ(traits_type::to_integral(pre), traits_type::to_entity(pre));
  422. registry.destroy(pre);
  423. const auto post = registry.create();
  424. ASSERT_NE(pre, post);
  425. ASSERT_EQ(traits_type::to_entity(pre), traits_type::to_entity(post));
  426. ASSERT_NE(traits_type::to_version(pre), traits_type::to_version(post));
  427. ASSERT_NE(traits_type::to_version(pre), registry.current(pre));
  428. ASSERT_EQ(traits_type::to_version(post), registry.current(post));
  429. const auto invalid = traits_type::combine(traits_type::to_entity(post) + 1u, {});
  430. ASSERT_EQ(traits_type::to_version(invalid), typename traits_type::version_type{});
  431. ASSERT_EQ(registry.current(invalid), traits_type::to_version(entt::tombstone));
  432. }
  433. TEST(Registry, MoreOnIdentifiers) {
  434. using traits_type = entt::entt_traits<entt::entity>;
  435. entt::registry registry{};
  436. const std::array entity{registry.create(), registry.create()};
  437. registry.destroy(entity[0]);
  438. ASSERT_FALSE(registry.valid(entity[0]));
  439. ASSERT_TRUE(registry.valid(entity[1]));
  440. ASSERT_EQ(registry.current(entt::null), traits_type::to_version(entt::tombstone));
  441. ASSERT_EQ(registry.current(entity[0]), traits_type::to_version(entity[0]) + 1u);
  442. ASSERT_EQ(registry.current(entity[1]), traits_type::to_version(entity[1]));
  443. registry.destroy(entity[1]);
  444. ASSERT_FALSE(registry.valid(entity[1]));
  445. ASSERT_EQ(registry.current(entity[1]), traits_type::to_version(entity[1]) + 1u);
  446. }
  447. TEST(Registry, VersionOverflow) {
  448. using traits_type = entt::entt_traits<entt::entity>;
  449. entt::registry registry{};
  450. const auto entity = registry.create();
  451. registry.destroy(entity);
  452. ASSERT_NE(registry.current(entity), traits_type::to_version(entity));
  453. ASSERT_NE(registry.current(entity), typename traits_type::version_type{});
  454. registry.destroy(registry.create(), traits_type::to_version(entt::tombstone) - 1u);
  455. registry.destroy(registry.create());
  456. ASSERT_EQ(registry.current(entity), traits_type::to_version(entity));
  457. ASSERT_EQ(registry.current(entity), typename traits_type::version_type{});
  458. }
  459. TEST(Registry, NullEntity) {
  460. entt::registry registry{};
  461. const entt::entity entity = entt::null;
  462. ASSERT_FALSE(registry.valid(entity));
  463. ASSERT_NE(registry.create(entity), entity);
  464. }
  465. TEST(Registry, TombstoneVersion) {
  466. using traits_type = entt::entt_traits<entt::entity>;
  467. entt::registry registry{};
  468. const entt::entity entity = entt::tombstone;
  469. ASSERT_FALSE(registry.valid(entity));
  470. const auto other = registry.create();
  471. const auto vers = traits_type::to_version(entity);
  472. const auto required = traits_type::construct(traits_type::to_entity(other), vers);
  473. ASSERT_NE(registry.destroy(other, vers), vers);
  474. ASSERT_NE(registry.create(required), required);
  475. }
  476. TEST(Registry, CreateManyEntitiesAtOnce) {
  477. using traits_type = entt::entt_traits<entt::entity>;
  478. entt::registry registry{};
  479. std::array<entt::entity, 3u> entity{};
  480. const auto entt = registry.create();
  481. registry.destroy(registry.create());
  482. registry.destroy(entt);
  483. registry.destroy(registry.create());
  484. registry.create(entity.begin(), entity.end());
  485. ASSERT_TRUE(registry.valid(entity[0]));
  486. ASSERT_TRUE(registry.valid(entity[1]));
  487. ASSERT_TRUE(registry.valid(entity[2]));
  488. ASSERT_EQ(traits_type::to_entity(entity[0]), 0u);
  489. ASSERT_EQ(traits_type::to_version(entity[0]), 2u);
  490. ASSERT_EQ(traits_type::to_entity(entity[1]), 1u);
  491. ASSERT_EQ(traits_type::to_version(entity[1]), 1u);
  492. ASSERT_EQ(traits_type::to_entity(entity[2]), 2u);
  493. ASSERT_EQ(traits_type::to_version(entity[2]), 0u);
  494. }
  495. TEST(Registry, CreateManyEntitiesAtOnceWithListener) {
  496. entt::registry registry{};
  497. std::array<entt::entity, 3u> entity{};
  498. listener listener;
  499. registry.on_construct<int>().connect<&listener::incr>(listener);
  500. registry.create(entity.begin(), entity.end());
  501. registry.insert(entity.begin(), entity.end(), 1);
  502. registry.insert(entity.begin(), entity.end(), 'c');
  503. ASSERT_EQ(registry.get<int>(entity[0]), 1);
  504. ASSERT_EQ(registry.get<char>(entity[1]), 'c');
  505. ASSERT_EQ(listener.counter, 3);
  506. registry.on_construct<int>().disconnect<&listener::incr>(listener);
  507. registry.on_construct<test::empty>().connect<&listener::incr>(listener);
  508. registry.create(entity.begin(), entity.end());
  509. registry.insert(entity.begin(), entity.end(), 'a');
  510. registry.insert<test::empty>(entity.begin(), entity.end());
  511. ASSERT_TRUE(registry.all_of<test::empty>(entity[0]));
  512. ASSERT_EQ(registry.get<char>(entity[2]), 'a');
  513. ASSERT_EQ(listener.counter, 6);
  514. }
  515. TEST(Registry, CreateWithHint) {
  516. using traits_type = entt::entt_traits<entt::entity>;
  517. entt::registry registry{};
  518. auto e3 = registry.create(entt::entity{3});
  519. auto e2 = registry.create(entt::entity{3});
  520. ASSERT_EQ(e2, entt::entity{0});
  521. ASSERT_FALSE(registry.valid(entt::entity{1}));
  522. ASSERT_FALSE(registry.valid(entt::entity{2}));
  523. ASSERT_EQ(e3, entt::entity{3});
  524. registry.destroy(e2);
  525. ASSERT_EQ(traits_type::to_version(e2), 0u);
  526. ASSERT_EQ(registry.current(e2), 1u);
  527. e2 = registry.create();
  528. auto e1 = registry.create(entt::entity{2});
  529. ASSERT_EQ(traits_type::to_entity(e2), 0u);
  530. ASSERT_EQ(traits_type::to_version(e2), 1u);
  531. ASSERT_EQ(traits_type::to_entity(e1), 2u);
  532. ASSERT_EQ(traits_type::to_version(e1), 0u);
  533. registry.destroy(e1);
  534. registry.destroy(e2);
  535. auto e0 = registry.create(entt::entity{0});
  536. ASSERT_EQ(e0, entt::entity{0});
  537. ASSERT_EQ(traits_type::to_version(e0), 0u);
  538. }
  539. TEST(Registry, CreateClearCycle) {
  540. using traits_type = entt::entt_traits<entt::entity>;
  541. entt::registry registry{};
  542. entt::entity pre{}, post{};
  543. const std::size_t first_iteration = 10u;
  544. const std::size_t second_iteration = 7u;
  545. const std::size_t third_iteration = 5u;
  546. for(std::size_t i{}; i < first_iteration; ++i) {
  547. const auto entity = registry.create();
  548. registry.emplace<double>(entity);
  549. }
  550. registry.clear();
  551. for(std::size_t i{}; i < second_iteration; ++i) {
  552. const auto entity = registry.create();
  553. registry.emplace<int>(entity);
  554. if(i == 3u) {
  555. pre = entity;
  556. }
  557. }
  558. registry.clear();
  559. for(std::size_t i{}; i < third_iteration; ++i) {
  560. const auto entity = registry.create();
  561. if(i == 3u) {
  562. post = entity;
  563. }
  564. }
  565. ASSERT_FALSE(registry.valid(pre));
  566. ASSERT_TRUE(registry.valid(post));
  567. ASSERT_NE(traits_type::to_version(pre), traits_type::to_version(post));
  568. ASSERT_EQ(traits_type::to_version(pre) + 1, traits_type::to_version(post));
  569. ASSERT_EQ(registry.current(pre), registry.current(post));
  570. }
  571. TEST(Registry, CreateDestroyReleaseCornerCase) {
  572. entt::registry registry{};
  573. const auto e0 = registry.create();
  574. const auto e1 = registry.create();
  575. registry.destroy(e0);
  576. registry.storage<entt::entity>().erase(e1);
  577. ASSERT_EQ(registry.storage<entt::entity>().free_list(), 0u);
  578. ASSERT_EQ(registry.current(e0), 1u);
  579. ASSERT_EQ(registry.current(e1), 1u);
  580. }
  581. ENTT_DEBUG_TEST(RegistryDeathTest, CreateTooManyEntities) {
  582. entt::basic_registry<test::entity> registry{};
  583. std::vector<test::entity> entity(entt::entt_traits<test::entity>::to_entity(entt::null));
  584. registry.create(entity.begin(), entity.end());
  585. ASSERT_DEATH([[maybe_unused]] const auto entt = registry.create(), "");
  586. }
  587. TEST(Registry, DestroyVersion) {
  588. entt::registry registry{};
  589. const auto e0 = registry.create();
  590. const auto e1 = registry.create();
  591. ASSERT_EQ(registry.current(e0), 0u);
  592. ASSERT_EQ(registry.current(e1), 0u);
  593. registry.destroy(e0);
  594. registry.destroy(e1, 3);
  595. ASSERT_EQ(registry.current(e0), 1u);
  596. ASSERT_EQ(registry.current(e1), 3u);
  597. }
  598. ENTT_DEBUG_TEST(RegistryDeathTest, DestroyVersion) {
  599. entt::registry registry{};
  600. const auto entity = registry.create();
  601. registry.destroy(entity);
  602. ASSERT_DEATH(registry.destroy(entity), "");
  603. ASSERT_DEATH(registry.destroy(entity, 3), "");
  604. }
  605. TEST(Registry, DestroyRange) {
  606. entt::registry registry{};
  607. const auto iview = registry.view<int>();
  608. const auto icview = registry.view<int, char>();
  609. std::array<entt::entity, 3u> entity{};
  610. registry.create(entity.begin(), entity.end());
  611. registry.emplace<int>(entity[0u]);
  612. registry.emplace<char>(entity[0u]);
  613. registry.emplace<double>(entity[0u]);
  614. registry.emplace<int>(entity[1u]);
  615. registry.emplace<char>(entity[1u]);
  616. registry.emplace<int>(entity[2u]);
  617. ASSERT_TRUE(registry.valid(entity[0u]));
  618. ASSERT_TRUE(registry.valid(entity[1u]));
  619. ASSERT_TRUE(registry.valid(entity[2u]));
  620. registry.destroy(icview.begin(), icview.end());
  621. ASSERT_FALSE(registry.valid(entity[0u]));
  622. ASSERT_FALSE(registry.valid(entity[1u]));
  623. ASSERT_TRUE(registry.valid(entity[2u]));
  624. ASSERT_EQ(registry.storage<int>().size(), 1u);
  625. ASSERT_EQ(registry.storage<char>().size(), 0u);
  626. ASSERT_EQ(registry.storage<double>().size(), 0u);
  627. registry.destroy(iview.begin(), iview.end());
  628. ASSERT_FALSE(registry.valid(entity[2u]));
  629. ASSERT_NO_THROW(registry.destroy(iview.rbegin(), iview.rend()));
  630. ASSERT_EQ(iview.size(), 0u);
  631. ASSERT_EQ(icview.size_hint(), 0u);
  632. ASSERT_EQ(registry.storage<int>().size(), 0u);
  633. ASSERT_EQ(registry.storage<char>().size(), 0u);
  634. ASSERT_EQ(registry.storage<double>().size(), 0u);
  635. registry.create(entity.begin(), entity.end());
  636. registry.insert<int>(entity.begin(), entity.end());
  637. ASSERT_TRUE(registry.valid(entity[0u]));
  638. ASSERT_TRUE(registry.valid(entity[1u]));
  639. ASSERT_TRUE(registry.valid(entity[2u]));
  640. ASSERT_EQ(registry.storage<int>().size(), 3u);
  641. registry.destroy(entity.begin(), entity.end());
  642. ASSERT_FALSE(registry.valid(entity[0u]));
  643. ASSERT_FALSE(registry.valid(entity[1u]));
  644. ASSERT_FALSE(registry.valid(entity[2u]));
  645. ASSERT_EQ(registry.storage<int>().size(), 0u);
  646. entt::sparse_set managed{};
  647. registry.create(entity.begin(), entity.end());
  648. managed.push(entity.begin(), entity.end());
  649. registry.insert<int>(managed.begin(), managed.end());
  650. ASSERT_TRUE(registry.valid(managed[0u]));
  651. ASSERT_TRUE(registry.valid(managed[1u]));
  652. ASSERT_TRUE(registry.valid(managed[2u]));
  653. ASSERT_EQ(registry.storage<int>().size(), 3u);
  654. registry.destroy(managed.begin(), managed.end());
  655. ASSERT_FALSE(registry.valid(managed[0u]));
  656. ASSERT_FALSE(registry.valid(managed[1u]));
  657. ASSERT_FALSE(registry.valid(managed[2u]));
  658. ASSERT_EQ(registry.storage<int>().size(), 0u);
  659. }
  660. TEST(Registry, StableDestroy) {
  661. entt::registry registry{};
  662. const auto iview = registry.view<int>();
  663. const auto icview = registry.view<int, test::pointer_stable>();
  664. std::array<entt::entity, 3u> entity{};
  665. registry.create(entity.begin(), entity.end());
  666. registry.emplace<int>(entity[0u]);
  667. registry.emplace<test::pointer_stable>(entity[0u]);
  668. registry.emplace<double>(entity[0u]);
  669. registry.emplace<int>(entity[1u]);
  670. registry.emplace<test::pointer_stable>(entity[1u]);
  671. registry.emplace<int>(entity[2u]);
  672. ASSERT_TRUE(registry.valid(entity[0u]));
  673. ASSERT_TRUE(registry.valid(entity[1u]));
  674. ASSERT_TRUE(registry.valid(entity[2u]));
  675. registry.destroy(icview.begin(), icview.end());
  676. ASSERT_FALSE(registry.valid(entity[0u]));
  677. ASSERT_FALSE(registry.valid(entity[1u]));
  678. ASSERT_TRUE(registry.valid(entity[2u]));
  679. ASSERT_EQ(registry.storage<int>().size(), 1u);
  680. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  681. ASSERT_EQ(registry.storage<double>().size(), 0u);
  682. registry.destroy(iview.begin(), iview.end());
  683. ASSERT_FALSE(registry.valid(entity[2u]));
  684. ASSERT_EQ(iview.size(), 0u);
  685. ASSERT_EQ(icview.size_hint(), 0u);
  686. ASSERT_EQ(registry.storage<int>().size(), 0u);
  687. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  688. ASSERT_EQ(registry.storage<double>().size(), 0u);
  689. }
  690. TEST(Registry, Emplace) {
  691. entt::registry registry{};
  692. const auto entity = registry.create();
  693. ASSERT_FALSE(registry.all_of<int>(entity));
  694. const auto &ref = registry.emplace<int>(entity, 4);
  695. ASSERT_TRUE(registry.all_of<int>(entity));
  696. ASSERT_EQ(registry.get<int>(entity), ref);
  697. ASSERT_EQ(ref, 4);
  698. }
  699. TEST(Registry, EmplaceTypesFromStandardTemplateLibrary) {
  700. // see #37 - the test shouldn't crash, that's all
  701. entt::registry registry{};
  702. const auto entity = registry.create();
  703. registry.emplace<std::unordered_set<int>>(entity).insert(1);
  704. registry.destroy(entity);
  705. }
  706. TEST(Registry, EmplaceWithComponents) {
  707. // it should compile, that's all
  708. entt::registry registry{};
  709. const auto value = 0;
  710. registry.emplace<int>(registry.create(), value);
  711. }
  712. TEST(Registry, EmplaceMoveOnlyComponent) {
  713. entt::registry registry{};
  714. // the purpose is to ensure that move only types are always accepted
  715. registry.emplace<std::unique_ptr<int>>(registry.create());
  716. }
  717. TEST(Registry, EmplaceNonDefaultConstructibleComponent) {
  718. entt::registry registry{};
  719. // the purpose is to ensure that non default constructible type are always accepted
  720. registry.emplace<test::non_default_constructible>(registry.create(), 1);
  721. }
  722. TEST(Registry, StableEmplace) {
  723. entt::registry registry{};
  724. registry.on_construct<int>().connect<&listener::sort<int>>();
  725. registry.emplace<int>(registry.create(), 0);
  726. ASSERT_EQ(registry.emplace<int>(registry.create(), 1), 1);
  727. }
  728. ENTT_DEBUG_TEST(RegistryDeathTest, Emplace) {
  729. entt::registry registry{};
  730. const auto entity = registry.create();
  731. registry.destroy(entity);
  732. ASSERT_DEATH(registry.emplace<int>(entity), "");
  733. }
  734. TEST(Registry, Insert) {
  735. entt::registry registry{};
  736. std::array<entt::entity, 3u> entity{};
  737. registry.create(entity.begin(), entity.end());
  738. registry.emplace<int>(entity[0u]);
  739. registry.emplace<char>(entity[0u]);
  740. registry.emplace<double>(entity[0u]);
  741. registry.emplace<int>(entity[1u]);
  742. registry.emplace<char>(entity[1u]);
  743. registry.emplace<int>(entity[2u]);
  744. ASSERT_FALSE(registry.all_of<float>(entity[0u]));
  745. ASSERT_FALSE(registry.all_of<float>(entity[1u]));
  746. ASSERT_FALSE(registry.all_of<float>(entity[2u]));
  747. const auto icview = registry.view<int, char>();
  748. registry.insert(icview.begin(), icview.end(), 3.f);
  749. ASSERT_EQ(registry.get<float>(entity[0u]), 3.f);
  750. ASSERT_EQ(registry.get<float>(entity[1u]), 3.f);
  751. ASSERT_FALSE(registry.all_of<float>(entity[2u]));
  752. registry.clear<float>();
  753. std::array value{0.f, 1.f, 2.f};
  754. const auto iview = registry.view<int>();
  755. registry.insert<float>(iview.rbegin(), iview.rend(), value.begin());
  756. ASSERT_EQ(registry.get<float>(entity[0u]), 0.f);
  757. ASSERT_EQ(registry.get<float>(entity[1u]), 1.f);
  758. ASSERT_EQ(registry.get<float>(entity[2u]), 2.f);
  759. }
  760. ENTT_DEBUG_TEST(RegistryDeathTest, Insert) {
  761. entt::registry registry{};
  762. const std::array entity{registry.create()};
  763. const std::array value{0};
  764. registry.destroy(entity[0]);
  765. ASSERT_DEATH(registry.insert<int>(entity.begin(), entity.end(), value[0]), "");
  766. ASSERT_DEATH(registry.insert<int>(entity.begin(), entity.end(), value.begin()), "");
  767. }
  768. TEST(Registry, EmplaceOrReplace) {
  769. entt::registry registry{};
  770. const auto entity = registry.create();
  771. ASSERT_FALSE(registry.all_of<int>(entity));
  772. const auto &ref = registry.emplace_or_replace<int>(entity, 4);
  773. ASSERT_TRUE(registry.all_of<int>(entity));
  774. ASSERT_EQ(registry.get<int>(entity), ref);
  775. ASSERT_EQ(ref, 4);
  776. registry.emplace_or_replace<int>(entity, 0);
  777. ASSERT_EQ(ref, 0);
  778. }
  779. TEST(Registry, EmplaceOrReplaceAggregate) {
  780. entt::registry registry{};
  781. const auto entity = registry.create();
  782. auto &instance = registry.emplace_or_replace<test::aggregate>(entity, 1);
  783. ASSERT_EQ(instance.value, 1);
  784. }
  785. ENTT_DEBUG_TEST(RegistryDeathTest, EmplaceOrReplace) {
  786. entt::registry registry{};
  787. const auto entity = registry.create();
  788. registry.destroy(entity);
  789. ASSERT_DEATH(registry.emplace_or_replace<int>(entity), "");
  790. }
  791. TEST(Registry, Patch) {
  792. entt::registry registry{};
  793. const auto entity = registry.create();
  794. registry.emplace<int>(entity, 3);
  795. ASSERT_EQ(registry.get<int>(entity), 3);
  796. registry.patch<int>(entity);
  797. ASSERT_EQ(registry.get<int>(entity), 3);
  798. registry.patch<int>(entity, [](auto &value) { value = 1; });
  799. ASSERT_EQ(registry.get<int>(entity), 1);
  800. }
  801. TEST(Registry, Replace) {
  802. entt::registry registry{};
  803. const auto entity = registry.create();
  804. registry.emplace<int>(entity, 3);
  805. ASSERT_EQ(registry.get<int>(entity), 3);
  806. registry.replace<int>(entity);
  807. ASSERT_EQ(registry.get<int>(entity), 0);
  808. registry.replace<int>(entity, 1);
  809. ASSERT_EQ(registry.get<int>(entity), 1);
  810. }
  811. TEST(Registry, ReplaceAggregate) {
  812. entt::registry registry{};
  813. const auto entity = registry.create();
  814. registry.emplace<test::aggregate>(entity, 0);
  815. auto &instance = registry.replace<test::aggregate>(entity, 1);
  816. ASSERT_EQ(instance.value, 1);
  817. }
  818. TEST(Registry, Remove) {
  819. entt::registry registry{};
  820. const auto iview = registry.view<int>();
  821. const auto icview = registry.view<int, char>();
  822. std::array<entt::entity, 3u> entity{};
  823. registry.create(entity.begin(), entity.end());
  824. registry.emplace<int>(entity[0u]);
  825. registry.emplace<char>(entity[0u]);
  826. registry.emplace<double>(entity[0u]);
  827. registry.emplace<int>(entity[1u]);
  828. registry.emplace<char>(entity[1u]);
  829. registry.emplace<int>(entity[2u]);
  830. ASSERT_TRUE(registry.any_of<int>(entity[0u]));
  831. ASSERT_TRUE(registry.all_of<int>(entity[1u]));
  832. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  833. registry.remove<int, char>(entity[0u]);
  834. ASSERT_EQ((registry.remove<int, char>(icview.begin(), icview.end())), 2u);
  835. ASSERT_EQ((registry.remove<int, char>(icview.begin(), icview.end())), 0u);
  836. ASSERT_FALSE(registry.any_of<int>(entity[0u]));
  837. ASSERT_FALSE(registry.all_of<int>(entity[1u]));
  838. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  839. ASSERT_EQ(registry.storage<int>().size(), 1u);
  840. ASSERT_EQ(registry.storage<char>().size(), 0u);
  841. ASSERT_EQ(registry.storage<double>().size(), 1u);
  842. ASSERT_EQ((registry.remove<int>(iview.begin(), iview.end())), 1u);
  843. ASSERT_EQ(registry.remove<int>(entity[0u]), 0u);
  844. ASSERT_EQ(registry.remove<int>(entity[1u]), 0u);
  845. ASSERT_FALSE(registry.any_of<int>(entity[2u]));
  846. ASSERT_EQ(registry.remove<int>(iview.begin(), iview.end()), 0u);
  847. ASSERT_EQ(registry.storage<int>().size(), 0u);
  848. ASSERT_EQ(registry.storage<char>().size(), 0u);
  849. ASSERT_EQ(registry.storage<double>().size(), 1u);
  850. registry.insert<int>(entity.begin() + 1u, entity.end() - 1u);
  851. registry.insert<char>(entity.begin() + 1u, entity.end() - 1u);
  852. ASSERT_EQ(registry.storage<int>().size(), 1u);
  853. ASSERT_EQ(registry.storage<char>().size(), 1u);
  854. registry.remove<int, char>(iview.begin(), iview.end());
  855. registry.remove<int, char>(iview.begin(), iview.end());
  856. ASSERT_EQ(registry.storage<int>().size(), 0u);
  857. ASSERT_EQ(registry.storage<char>().size(), 0u);
  858. registry.insert<int>(entity.begin(), entity.end());
  859. registry.insert<char>(entity.begin(), entity.end());
  860. ASSERT_EQ(registry.storage<int>().size(), 3u);
  861. ASSERT_EQ(registry.storage<char>().size(), 3u);
  862. registry.remove<int, char>(entity.begin(), entity.end());
  863. registry.remove<int, char>(entity.begin(), entity.end());
  864. ASSERT_EQ(registry.storage<int>().size(), 0u);
  865. ASSERT_EQ(registry.storage<char>().size(), 0u);
  866. ASSERT_FALSE(registry.orphan(entity[0u]));
  867. ASSERT_TRUE(registry.orphan(entity[1u]));
  868. ASSERT_TRUE(registry.orphan(entity[2u]));
  869. }
  870. TEST(Registry, StableRemove) {
  871. entt::registry registry{};
  872. const auto iview = registry.view<int>();
  873. const auto icview = registry.view<int, test::pointer_stable>();
  874. std::array<entt::entity, 3u> entity{};
  875. registry.create(entity.begin(), entity.end());
  876. registry.emplace<int>(entity[0u]);
  877. registry.emplace<test::pointer_stable>(entity[0u]);
  878. registry.emplace<double>(entity[0u]);
  879. registry.emplace<int>(entity[1u]);
  880. registry.emplace<test::pointer_stable>(entity[1u]);
  881. registry.emplace<int>(entity[2u]);
  882. ASSERT_TRUE(registry.any_of<int>(entity[0u]));
  883. ASSERT_TRUE(registry.all_of<int>(entity[1u]));
  884. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  885. registry.remove<int, test::pointer_stable>(entity[0u]);
  886. ASSERT_EQ((registry.remove<int, test::pointer_stable>(icview.begin(), icview.end())), 2u);
  887. ASSERT_EQ((registry.remove<int, test::pointer_stable>(icview.begin(), icview.end())), 0u);
  888. ASSERT_FALSE(registry.any_of<int>(entity[0u]));
  889. ASSERT_FALSE(registry.all_of<int>(entity[1u]));
  890. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  891. ASSERT_EQ(registry.storage<int>().size(), 1u);
  892. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  893. ASSERT_EQ(registry.storage<double>().size(), 1u);
  894. ASSERT_EQ((registry.remove<int>(iview.begin(), iview.end())), 1u);
  895. ASSERT_EQ(registry.remove<int>(entity[0u]), 0u);
  896. ASSERT_EQ(registry.remove<int>(entity[1u]), 0u);
  897. ASSERT_FALSE(registry.any_of<int>(entity[2u]));
  898. ASSERT_EQ(registry.storage<int>().size(), 0u);
  899. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  900. ASSERT_EQ(registry.storage<double>().size(), 1u);
  901. }
  902. TEST(Registry, Erase) {
  903. entt::registry registry{};
  904. const auto iview = registry.view<int>();
  905. const auto icview = registry.view<int, char>();
  906. std::array<entt::entity, 3u> entity{};
  907. registry.create(entity.begin(), entity.end());
  908. registry.emplace<int>(entity[0u]);
  909. registry.emplace<char>(entity[0u]);
  910. registry.emplace<double>(entity[0u]);
  911. registry.emplace<int>(entity[1u]);
  912. registry.emplace<char>(entity[1u]);
  913. registry.emplace<int>(entity[2u]);
  914. ASSERT_TRUE(registry.any_of<int>(entity[0u]));
  915. ASSERT_TRUE(registry.all_of<int>(entity[1u]));
  916. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  917. registry.erase<int, char>(entity[0u]);
  918. registry.erase<int, char>(icview.begin(), icview.end());
  919. ASSERT_FALSE(registry.any_of<int>(entity[0u]));
  920. ASSERT_FALSE(registry.all_of<int>(entity[1u]));
  921. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  922. ASSERT_EQ(registry.storage<int>().size(), 1u);
  923. ASSERT_EQ(registry.storage<char>().size(), 0u);
  924. ASSERT_EQ(registry.storage<double>().size(), 1u);
  925. registry.erase<int>(iview.begin(), iview.end());
  926. ASSERT_FALSE(registry.any_of<int>(entity[2u]));
  927. ASSERT_NO_THROW(registry.erase<int>(iview.rbegin(), iview.rend()));
  928. ASSERT_EQ(registry.storage<int>().size(), 0u);
  929. ASSERT_EQ(registry.storage<char>().size(), 0u);
  930. ASSERT_EQ(registry.storage<double>().size(), 1u);
  931. registry.insert<int>(entity.begin() + 1u, entity.end() - 1u);
  932. registry.insert<char>(entity.begin() + 1u, entity.end() - 1u);
  933. ASSERT_EQ(registry.storage<int>().size(), 1u);
  934. ASSERT_EQ(registry.storage<char>().size(), 1u);
  935. registry.erase<int, char>(iview.begin(), iview.end());
  936. ASSERT_EQ(registry.storage<int>().size(), 0u);
  937. ASSERT_EQ(registry.storage<char>().size(), 0u);
  938. registry.insert<int>(entity.begin(), entity.end());
  939. registry.insert<char>(entity.begin(), entity.end());
  940. ASSERT_EQ(registry.storage<int>().size(), 3u);
  941. ASSERT_EQ(registry.storage<char>().size(), 3u);
  942. registry.erase<int, char>(entity.begin(), entity.end());
  943. ASSERT_EQ(registry.storage<int>().size(), 0u);
  944. ASSERT_EQ(registry.storage<char>().size(), 0u);
  945. ASSERT_FALSE(registry.orphan(entity[0u]));
  946. ASSERT_TRUE(registry.orphan(entity[1u]));
  947. ASSERT_TRUE(registry.orphan(entity[2u]));
  948. }
  949. ENTT_DEBUG_TEST(RegistryDeathTest, Erase) {
  950. entt::registry registry{};
  951. const std::array entity{registry.create()};
  952. ASSERT_FALSE((registry.any_of<int>(entity[0u])));
  953. ASSERT_DEATH((registry.erase<int>(entity.begin(), entity.end())), "");
  954. ASSERT_DEATH(registry.erase<int>(entity[0u]), "");
  955. }
  956. TEST(Registry, StableErase) {
  957. entt::registry registry{};
  958. const auto iview = registry.view<int>();
  959. const auto icview = registry.view<int, test::pointer_stable>();
  960. std::array<entt::entity, 3u> entity{};
  961. registry.create(entity.begin(), entity.end());
  962. registry.emplace<int>(entity[0u]);
  963. registry.emplace<test::pointer_stable>(entity[0u]);
  964. registry.emplace<double>(entity[0u]);
  965. registry.emplace<int>(entity[1u]);
  966. registry.emplace<test::pointer_stable>(entity[1u]);
  967. registry.emplace<int>(entity[2u]);
  968. ASSERT_TRUE(registry.any_of<int>(entity[0u]));
  969. ASSERT_TRUE(registry.all_of<int>(entity[1u]));
  970. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  971. registry.erase<int, test::pointer_stable>(entity[0u]);
  972. registry.erase<int, test::pointer_stable>(icview.begin(), icview.end());
  973. registry.erase<int, test::pointer_stable>(icview.begin(), icview.end());
  974. ASSERT_FALSE(registry.any_of<int>(entity[0u]));
  975. ASSERT_FALSE(registry.all_of<int>(entity[1u]));
  976. ASSERT_TRUE(registry.any_of<int>(entity[2u]));
  977. ASSERT_EQ(registry.storage<int>().size(), 1u);
  978. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  979. ASSERT_EQ(registry.storage<double>().size(), 1u);
  980. registry.erase<int>(iview.begin(), iview.end());
  981. ASSERT_FALSE(registry.any_of<int>(entity[2u]));
  982. ASSERT_EQ(registry.storage<int>().size(), 0u);
  983. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  984. ASSERT_EQ(registry.storage<double>().size(), 1u);
  985. }
  986. TEST(Registry, EraseIf) {
  987. using namespace entt::literals;
  988. entt::registry registry{};
  989. const auto entity = registry.create();
  990. registry.emplace<int>(entity);
  991. registry.storage<int>("other"_hs).emplace(entity);
  992. registry.emplace<char>(entity);
  993. ASSERT_TRUE(registry.storage<int>().contains(entity));
  994. ASSERT_TRUE(registry.storage<int>("other"_hs).contains(entity));
  995. ASSERT_TRUE(registry.storage<char>().contains(entity));
  996. registry.erase_if(entity, [](auto &&...) { return false; });
  997. ASSERT_TRUE(registry.storage<int>().contains(entity));
  998. ASSERT_TRUE(registry.storage<int>("other"_hs).contains(entity));
  999. ASSERT_TRUE(registry.storage<char>().contains(entity));
  1000. registry.erase_if(entity, [](entt::id_type id, auto &&...) { return id == "other"_hs; });
  1001. ASSERT_TRUE(registry.storage<int>().contains(entity));
  1002. ASSERT_FALSE(registry.storage<int>("other"_hs).contains(entity));
  1003. ASSERT_TRUE(registry.storage<char>().contains(entity));
  1004. registry.erase_if(entity, [](auto, const auto &storage) { return storage.type() == entt::type_id<char>(); });
  1005. ASSERT_TRUE(registry.storage<int>().contains(entity));
  1006. ASSERT_FALSE(registry.storage<int>("other"_hs).contains(entity));
  1007. ASSERT_FALSE(registry.storage<char>().contains(entity));
  1008. }
  1009. TEST(Registry, Compact) {
  1010. entt::registry registry{};
  1011. std::array<entt::entity, 2u> entity{};
  1012. registry.create(entity.begin(), entity.end());
  1013. registry.emplace<int>(entity[0u]);
  1014. registry.emplace<test::pointer_stable>(entity[0u]);
  1015. registry.emplace<int>(entity[1u]);
  1016. registry.emplace<test::pointer_stable>(entity[1u]);
  1017. ASSERT_EQ(registry.storage<int>().size(), 2u);
  1018. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  1019. registry.destroy(entity.begin(), entity.end());
  1020. ASSERT_EQ(registry.storage<int>().size(), 0u);
  1021. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  1022. registry.compact<int>();
  1023. ASSERT_EQ(registry.storage<int>().size(), 0u);
  1024. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 2u);
  1025. registry.compact();
  1026. ASSERT_EQ(registry.storage<int>().size(), 0u);
  1027. ASSERT_EQ(registry.storage<test::pointer_stable>().size(), 0u);
  1028. }
  1029. TEST(Registry, AllAnyOf) {
  1030. entt::registry registry{};
  1031. const auto entity = registry.create();
  1032. ASSERT_FALSE(registry.all_of<int>(entity));
  1033. ASSERT_FALSE((registry.all_of<int, char>(entity)));
  1034. ASSERT_FALSE((registry.any_of<int, char>(entity)));
  1035. registry.emplace<int>(entity);
  1036. ASSERT_TRUE(registry.all_of<int>(entity));
  1037. ASSERT_FALSE((registry.all_of<int, char>(entity)));
  1038. ASSERT_TRUE((registry.any_of<int, char>(entity)));
  1039. registry.emplace<char>(entity);
  1040. ASSERT_TRUE(registry.all_of<int>(entity));
  1041. ASSERT_TRUE((registry.all_of<int, char>(entity)));
  1042. ASSERT_TRUE((registry.any_of<int, char>(entity)));
  1043. }
  1044. TEST(Registry, Get) {
  1045. entt::registry registry{};
  1046. const auto entity = registry.create();
  1047. registry.emplace<int>(entity, 1);
  1048. registry.emplace<char>(entity, 'c');
  1049. ASSERT_EQ(std::as_const(registry).get<int>(entity), 1);
  1050. ASSERT_EQ((std::as_const(registry).get<int, char>(entity)), std::make_tuple(1, 'c'));
  1051. registry.get<int>(entity) = 3;
  1052. std::get<1>(registry.get<int, char>(entity)) = 'a';
  1053. ASSERT_EQ(registry.get<int>(entity), 3);
  1054. ASSERT_EQ((registry.get<int, char>(entity)), std::make_tuple(3, 'a'));
  1055. }
  1056. TEST(Registry, GetOrEmplace) {
  1057. entt::registry registry{};
  1058. const auto entity = registry.create();
  1059. const auto value = registry.get_or_emplace<int>(entity, 3);
  1060. // get_or_emplace must work for empty types
  1061. static_cast<void>(registry.get_or_emplace<test::empty>(entity));
  1062. ASSERT_TRUE((registry.all_of<int, test::empty>(entity)));
  1063. ASSERT_EQ(registry.get<int>(entity), value);
  1064. ASSERT_EQ(registry.get<int>(entity), 3);
  1065. }
  1066. ENTT_DEBUG_TEST(RegistryDeathTest, GetOrEmplace) {
  1067. entt::registry registry{};
  1068. const auto entity = registry.create();
  1069. registry.destroy(entity);
  1070. ASSERT_DEATH([[maybe_unused]] const auto value = registry.get_or_emplace<int>(entity), "");
  1071. }
  1072. TEST(Registry, TryGet) {
  1073. entt::registry registry{};
  1074. const auto entity = registry.create();
  1075. ASSERT_EQ(registry.try_get<int>(entity), nullptr);
  1076. ASSERT_EQ(std::as_const(registry).try_get<int>(entity), nullptr);
  1077. ASSERT_EQ(std::as_const(registry).storage<int>(), nullptr);
  1078. const int &elem = registry.emplace<int>(entity);
  1079. ASSERT_NE(std::as_const(registry).storage<int>(), nullptr);
  1080. ASSERT_EQ(registry.try_get<int>(entity), &elem);
  1081. ASSERT_EQ(std::as_const(registry).try_get<int>(entity), &elem);
  1082. }
  1083. TEST(Registry, Clear) {
  1084. entt::registry registry{};
  1085. const std::array entity{registry.create(), registry.create()};
  1086. registry.insert<int>(entity.begin(), entity.end());
  1087. registry.insert<char>(entity.begin(), entity.end());
  1088. ASSERT_TRUE((registry.all_of<int, char>(entity[0])));
  1089. ASSERT_TRUE((registry.all_of<int, char>(entity[1])));
  1090. registry.clear<int>();
  1091. ASSERT_TRUE(registry.valid(entity[0]));
  1092. ASSERT_TRUE(registry.valid(entity[1]));
  1093. ASSERT_FALSE(registry.all_of<int>(entity[0]));
  1094. ASSERT_FALSE(registry.all_of<int>(entity[1]));
  1095. ASSERT_TRUE(registry.all_of<char>(entity[0]));
  1096. ASSERT_TRUE(registry.all_of<char>(entity[1]));
  1097. registry.clear();
  1098. ASSERT_FALSE(registry.valid(entity[0]));
  1099. ASSERT_FALSE(registry.valid(entity[1]));
  1100. ASSERT_TRUE(registry.storage<int>().empty());
  1101. ASSERT_TRUE(registry.storage<char>().empty());
  1102. }
  1103. TEST(Registry, Orphan) {
  1104. entt::registry registry{};
  1105. std::array<entt::entity, 3u> entity{};
  1106. registry.create(entity.begin(), entity.end());
  1107. registry.emplace<int>(entity[0u]);
  1108. registry.emplace<int>(entity[2u]);
  1109. for(auto [entt]: registry.storage<entt::entity>().each()) {
  1110. ASSERT_TRUE(entt != entity[1u] || registry.orphan(entt));
  1111. }
  1112. registry.erase<int>(entity[0u]);
  1113. registry.erase<int>(entity[2u]);
  1114. for(auto [entt]: registry.storage<entt::entity>().each()) {
  1115. ASSERT_TRUE(registry.orphan(entt));
  1116. }
  1117. }
  1118. TEST(Registry, Signals) {
  1119. entt::registry registry{};
  1120. std::array<entt::entity, 2u> entity{};
  1121. listener listener;
  1122. registry.on_construct<test::empty>().connect<&listener::incr>(listener);
  1123. registry.on_destroy<test::empty>().connect<&listener::decr>(listener);
  1124. registry.on_construct<int>().connect<&listener::incr>(listener);
  1125. registry.on_destroy<int>().connect<&listener::decr>(listener);
  1126. registry.create(entity.begin(), entity.end());
  1127. registry.insert<test::empty>(entity.begin(), entity.end());
  1128. ASSERT_EQ(listener.counter, 2);
  1129. ASSERT_EQ(listener.last, entity[1u]);
  1130. registry.insert<int>(entity.rbegin(), entity.rend());
  1131. ASSERT_EQ(listener.counter, 4);
  1132. ASSERT_EQ(listener.last, entity[0u]);
  1133. registry.erase<test::empty, int>(entity[0u]);
  1134. ASSERT_EQ(listener.counter, 2);
  1135. ASSERT_EQ(listener.last, entity[0u]);
  1136. registry.on_destroy<test::empty>().disconnect<&listener::decr>(listener);
  1137. registry.on_destroy<int>().disconnect<&listener::decr>(listener);
  1138. registry.erase<test::empty, int>(entity[1u]);
  1139. ASSERT_EQ(listener.counter, 2);
  1140. ASSERT_EQ(listener.last, entity[0u]);
  1141. registry.on_construct<test::empty>().disconnect<&listener::incr>(listener);
  1142. registry.on_construct<int>().disconnect<&listener::incr>(listener);
  1143. registry.emplace<test::empty>(entity[1u]);
  1144. registry.emplace<int>(entity[1u]);
  1145. ASSERT_EQ(listener.counter, 2);
  1146. ASSERT_EQ(listener.last, entity[0u]);
  1147. registry.on_construct<int>().connect<&listener::incr>(listener);
  1148. registry.on_destroy<int>().connect<&listener::decr>(listener);
  1149. registry.emplace<int>(entity[0u]);
  1150. registry.erase<int>(entity[1u]);
  1151. ASSERT_EQ(listener.counter, 2);
  1152. ASSERT_EQ(listener.last, entity[1u]);
  1153. registry.on_construct<test::empty>().connect<&listener::incr>(listener);
  1154. registry.on_destroy<test::empty>().connect<&listener::decr>(listener);
  1155. registry.erase<test::empty>(entity[1u]);
  1156. registry.emplace<test::empty>(entity[0u]);
  1157. ASSERT_EQ(listener.counter, 2);
  1158. ASSERT_EQ(listener.last, entity[0u]);
  1159. registry.clear<test::empty, int>();
  1160. ASSERT_EQ(listener.counter, 0);
  1161. ASSERT_EQ(listener.last, entity[0u]);
  1162. registry.insert<test::empty>(entity.begin(), entity.end());
  1163. registry.insert<int>(entity.begin(), entity.end());
  1164. registry.destroy(entity[1u]);
  1165. ASSERT_EQ(listener.counter, 2);
  1166. ASSERT_EQ(listener.last, entity[1u]);
  1167. registry.erase<int, test::empty>(entity[0u]);
  1168. registry.emplace_or_replace<int>(entity[0u]);
  1169. registry.emplace_or_replace<test::empty>(entity[0u]);
  1170. ASSERT_EQ(listener.counter, 2);
  1171. ASSERT_EQ(listener.last, entity[0u]);
  1172. registry.on_destroy<test::empty>().disconnect<&listener::decr>(listener);
  1173. registry.on_destroy<int>().disconnect<&listener::decr>(listener);
  1174. registry.emplace_or_replace<test::empty>(entity[0u]);
  1175. registry.emplace_or_replace<int>(entity[0u]);
  1176. ASSERT_EQ(listener.counter, 2);
  1177. ASSERT_EQ(listener.last, entity[0u]);
  1178. registry.on_update<test::empty>().connect<&listener::incr>(listener);
  1179. registry.on_update<int>().connect<&listener::incr>(listener);
  1180. registry.emplace_or_replace<test::empty>(entity[0u]);
  1181. registry.emplace_or_replace<int>(entity[0u]);
  1182. ASSERT_EQ(listener.counter, 4);
  1183. ASSERT_EQ(listener.last, entity[0u]);
  1184. registry.replace<test::empty>(entity[0u]);
  1185. registry.replace<int>(entity[0u]);
  1186. ASSERT_EQ(listener.counter, 6);
  1187. ASSERT_EQ(listener.last, entity[0u]);
  1188. }
  1189. TEST(Registry, SignalsOnRuntimePool) {
  1190. using namespace entt::literals;
  1191. entt::registry registry{};
  1192. const auto entity = registry.create();
  1193. listener listener;
  1194. registry.on_construct<int>("custom"_hs).connect<&listener::incr>(listener);
  1195. registry.on_update<int>("custom"_hs).connect<&listener::incr>(listener);
  1196. registry.on_destroy<int>("custom"_hs).connect<&listener::incr>(listener);
  1197. ASSERT_EQ(listener.counter, 0);
  1198. registry.emplace<int>(entity);
  1199. registry.patch<int>(entity);
  1200. registry.erase<int>(entity);
  1201. ASSERT_EQ(listener.counter, 0);
  1202. registry.storage<int>("custom"_hs).emplace(entity);
  1203. registry.storage<int>("custom"_hs).patch(entity);
  1204. registry.storage<int>("custom"_hs).erase(entity);
  1205. ASSERT_EQ(listener.counter, 3);
  1206. }
  1207. TEST(Registry, SignalsOnEntity) {
  1208. entt::registry registry{};
  1209. listener listener;
  1210. registry.on_construct<entt::entity>().connect<&listener::incr>(listener);
  1211. entt::entity entity = registry.create();
  1212. entt::entity other = registry.create();
  1213. ASSERT_EQ(listener.counter, 2);
  1214. ASSERT_EQ(listener.last, other);
  1215. registry.destroy(other);
  1216. registry.destroy(entity);
  1217. ASSERT_EQ(listener.counter, 2);
  1218. ASSERT_EQ(listener.last, other);
  1219. registry.on_construct<entt::entity>().disconnect(&listener);
  1220. other = registry.create();
  1221. entity = registry.create();
  1222. ASSERT_EQ(listener.counter, 2);
  1223. ASSERT_NE(listener.last, entity);
  1224. ASSERT_NE(listener.last, other);
  1225. registry.on_update<entt::entity>().connect<&listener::decr>(listener);
  1226. registry.patch<entt::entity>(entity);
  1227. ASSERT_EQ(listener.counter, 1);
  1228. ASSERT_EQ(listener.last, entity);
  1229. registry.on_update<entt::entity>().disconnect(&listener);
  1230. registry.patch<entt::entity>(other);
  1231. ASSERT_EQ(listener.counter, 1);
  1232. ASSERT_NE(listener.last, other);
  1233. registry.on_destroy<entt::entity>().connect<&listener::decr>(listener);
  1234. registry.destroy(entity);
  1235. ASSERT_EQ(listener.counter, 0);
  1236. ASSERT_EQ(listener.last, entity);
  1237. registry.on_destroy<entt::entity>().disconnect(&listener);
  1238. registry.destroy(other);
  1239. ASSERT_EQ(listener.counter, 0);
  1240. ASSERT_NE(listener.last, other);
  1241. }
  1242. TEST(Registry, SignalWhenDestroying) {
  1243. entt::registry registry{};
  1244. const auto entity = registry.create();
  1245. registry.on_destroy<double>().connect<&entt::registry::remove<char>>();
  1246. registry.emplace<double>(entity);
  1247. registry.emplace<int>(entity);
  1248. ASSERT_NE(registry.storage(entt::type_id<double>().hash()), nullptr);
  1249. ASSERT_NE(registry.storage(entt::type_id<int>().hash()), nullptr);
  1250. ASSERT_EQ(registry.storage(entt::type_id<char>().hash()), nullptr);
  1251. ASSERT_TRUE(registry.valid(entity));
  1252. registry.destroy(entity);
  1253. ASSERT_NE(registry.storage(entt::type_id<char>().hash()), nullptr);
  1254. ASSERT_FALSE(registry.valid(entity));
  1255. }
  1256. TEST(Registry, SelfSignal) {
  1257. entt::registry registry{};
  1258. const auto entity = registry.create();
  1259. // required because of an issue of VS2019
  1260. constexpr auto emplace_or_replace = &entt::registry::emplace_or_replace<double>;
  1261. constexpr auto remove = &entt::registry::remove<double>;
  1262. registry.on_construct<int>().connect<emplace_or_replace>();
  1263. registry.on_destroy<int>().connect<remove>();
  1264. registry.emplace<double>(entity, .3);
  1265. ASSERT_FALSE(registry.all_of<int>(entity));
  1266. ASSERT_EQ(registry.get<double>(entity), .3);
  1267. registry.emplace<int>(entity);
  1268. ASSERT_TRUE(registry.all_of<int>(entity));
  1269. ASSERT_EQ(registry.get<double>(entity), .0);
  1270. registry.erase<int>(entity);
  1271. ASSERT_FALSE((registry.any_of<int, double>(entity)));
  1272. registry.on_construct<int>().disconnect<emplace_or_replace>();
  1273. registry.on_destroy<int>().disconnect<remove>();
  1274. registry.emplace<int>(entity);
  1275. ASSERT_TRUE((registry.any_of<int, double>(entity)));
  1276. ASSERT_FALSE(registry.all_of<double>(entity));
  1277. }
  1278. TEST(Registry, View) {
  1279. entt::registry registry{};
  1280. std::array<entt::entity, 3u> entity{};
  1281. auto iview = std::as_const(registry).view<int>();
  1282. auto cview = std::as_const(registry).view<char>();
  1283. ASSERT_FALSE(iview);
  1284. ASSERT_FALSE(cview);
  1285. ASSERT_EQ(std::as_const(registry).storage<int>(), nullptr);
  1286. ASSERT_EQ(std::as_const(registry).storage<char>(), nullptr);
  1287. auto mview = registry.view<int, char>();
  1288. auto fview = registry.view<int>(entt::exclude<char>);
  1289. ASSERT_TRUE(mview);
  1290. ASSERT_TRUE(fview);
  1291. ASSERT_NE(std::as_const(registry).storage<int>(), nullptr);
  1292. ASSERT_NE(std::as_const(registry).storage<char>(), nullptr);
  1293. iview = std::as_const(registry).view<int>();
  1294. cview = std::as_const(registry).view<char>();
  1295. ASSERT_TRUE(iview);
  1296. ASSERT_TRUE(cview);
  1297. registry.create(entity.begin(), entity.end());
  1298. registry.emplace<int>(entity[0u], 0);
  1299. registry.emplace<char>(entity[0u], 'c');
  1300. registry.emplace<int>(entity[1u], 0);
  1301. registry.emplace<int>(entity[2u], 0);
  1302. registry.emplace<char>(entity[2u], 'c');
  1303. ASSERT_EQ(iview.size(), 3u);
  1304. ASSERT_EQ(cview.size(), 2u);
  1305. ASSERT_EQ(mview.size_hint(), 3u);
  1306. ASSERT_EQ(fview.size_hint(), 3u);
  1307. mview.refresh();
  1308. ASSERT_EQ(mview.size_hint(), 2u);
  1309. ASSERT_EQ(fview.size_hint(), 3u);
  1310. ASSERT_NE(mview.begin(), mview.end());
  1311. ASSERT_NE(fview.begin(), fview.end());
  1312. ASSERT_EQ(std::distance(mview.begin(), mview.end()), 2);
  1313. ASSERT_EQ(std::distance(fview.begin(), fview.end()), 1);
  1314. mview.each([&entity, first = true](auto entt, auto &&...) mutable {
  1315. ASSERT_EQ(entt, first ? entity[2u] : entity[0u]);
  1316. first = false;
  1317. });
  1318. fview.each([&entity](auto entt, auto &&...) {
  1319. ASSERT_EQ(entt, entity[1u]);
  1320. });
  1321. }
  1322. TEST(Registry, ExcludeOnlyView) {
  1323. entt::registry registry{};
  1324. std::array<entt::entity, 4u> entity{};
  1325. auto view = registry.view<entt::entity>(entt::exclude<int>);
  1326. registry.create(entity.begin(), entity.end());
  1327. registry.emplace<int>(entity[0u], 0);
  1328. registry.emplace<int>(entity[2u], 0);
  1329. registry.emplace<int>(entity[3u], 0);
  1330. registry.destroy(entity[3u]);
  1331. ASSERT_EQ(view.size_hint(), 4u);
  1332. ASSERT_NE(view.begin(), view.end());
  1333. ASSERT_EQ(std::distance(view.begin(), view.end()), 1);
  1334. ASSERT_EQ(*view.begin(), entity[1u]);
  1335. for(auto [entt]: view.each()) {
  1336. ASSERT_EQ(entt, entity[1u]);
  1337. }
  1338. view.each([&entity](auto entt) {
  1339. ASSERT_EQ(entt, entity[1u]);
  1340. });
  1341. }
  1342. TEST(Registry, CleanViewAfterRemoveAndClear) {
  1343. entt::registry registry{};
  1344. auto view = registry.view<int, char>();
  1345. const auto entity = registry.create();
  1346. registry.emplace<int>(entity);
  1347. registry.emplace<char>(entity);
  1348. ASSERT_EQ(view.size_hint(), 1u);
  1349. registry.erase<char>(entity);
  1350. ASSERT_EQ(view.size_hint(), 1u);
  1351. registry.emplace<char>(entity);
  1352. ASSERT_EQ(view.size_hint(), 1u);
  1353. registry.clear<int>();
  1354. ASSERT_EQ(view.size_hint(), 0u);
  1355. registry.emplace<int>(entity);
  1356. ASSERT_EQ(view.size_hint(), 1u);
  1357. registry.clear();
  1358. ASSERT_EQ(view.size_hint(), 0u);
  1359. }
  1360. TEST(Registry, NonOwningGroupInitOnFirstUse) {
  1361. entt::registry registry{};
  1362. std::array<entt::entity, 3u> entity{};
  1363. registry.create(entity.begin(), entity.end());
  1364. registry.insert<int>(entity.begin(), entity.end(), 0);
  1365. registry.emplace<char>(entity[0u], 'c');
  1366. registry.emplace<char>(entity[2u], 'c');
  1367. std::size_t cnt{};
  1368. auto group = registry.group(entt::get<int, char>);
  1369. group.each([&cnt](auto...) { ++cnt; });
  1370. ASSERT_FALSE((registry.owned<int, char>()));
  1371. ASSERT_EQ(cnt, 2u);
  1372. }
  1373. TEST(Registry, NonOwningGroupInitOnEmplace) {
  1374. entt::registry registry{};
  1375. std::array<entt::entity, 3u> entity{};
  1376. auto group = registry.group(entt::get<int, char>);
  1377. registry.create(entity.begin(), entity.end());
  1378. registry.insert<int>(entity.begin(), entity.end(), 0);
  1379. registry.emplace<char>(entity[0u], 'c');
  1380. registry.emplace<char>(entity[2u], 'c');
  1381. std::size_t cnt{};
  1382. group.each([&cnt](auto...) { ++cnt; });
  1383. ASSERT_FALSE((registry.owned<int, char>()));
  1384. ASSERT_EQ(cnt, 2u);
  1385. }
  1386. TEST(Registry, FullOwningGroupInitOnFirstUse) {
  1387. entt::registry registry{};
  1388. std::array<entt::entity, 3u> entity{};
  1389. registry.create(entity.begin(), entity.end());
  1390. registry.insert<int>(entity.begin(), entity.end(), 0);
  1391. registry.emplace<char>(entity[0u], 'c');
  1392. registry.emplace<char>(entity[2u], 'c');
  1393. std::size_t cnt{};
  1394. auto group = registry.group<int, char>();
  1395. group.each([&cnt](auto...) { ++cnt; });
  1396. ASSERT_TRUE(registry.owned<int>());
  1397. ASSERT_TRUE(registry.owned<char>());
  1398. ASSERT_FALSE(registry.owned<double>());
  1399. ASSERT_EQ(cnt, 2u);
  1400. }
  1401. TEST(Registry, FullOwningGroupInitOnEmplace) {
  1402. entt::registry registry{};
  1403. std::array<entt::entity, 3u> entity{};
  1404. auto group = registry.group<int, char>();
  1405. registry.create(entity.begin(), entity.end());
  1406. registry.insert<int>(entity.begin(), entity.end(), 0);
  1407. registry.emplace<char>(entity[0u], 'c');
  1408. registry.emplace<char>(entity[2u], 'c');
  1409. std::size_t cnt{};
  1410. group.each([&cnt](auto...) { ++cnt; });
  1411. ASSERT_TRUE(registry.owned<int>());
  1412. ASSERT_TRUE(registry.owned<char>());
  1413. ASSERT_FALSE(registry.owned<double>());
  1414. ASSERT_EQ(cnt, 2u);
  1415. }
  1416. TEST(Registry, PartialOwningGroupInitOnFirstUse) {
  1417. entt::registry registry{};
  1418. std::array<entt::entity, 3u> entity{};
  1419. registry.create(entity.begin(), entity.end());
  1420. registry.insert<int>(entity.begin(), entity.end(), 0);
  1421. registry.emplace<char>(entity[0u], 'c');
  1422. registry.emplace<char>(entity[2u], 'c');
  1423. std::size_t cnt{};
  1424. auto group = registry.group<int>(entt::get<char>);
  1425. group.each([&cnt](auto...) { ++cnt; });
  1426. ASSERT_TRUE((registry.owned<int, char>()));
  1427. ASSERT_TRUE(registry.owned<int>());
  1428. ASSERT_FALSE(registry.owned<char>());
  1429. ASSERT_EQ(cnt, 2u);
  1430. }
  1431. TEST(Registry, PartialOwningGroupInitOnEmplace) {
  1432. entt::registry registry{};
  1433. std::array<entt::entity, 3u> entity{};
  1434. auto group = registry.group<int>(entt::get<char>);
  1435. registry.create(entity.begin(), entity.end());
  1436. registry.insert<int>(entity.begin(), entity.end(), 0);
  1437. registry.emplace<char>(entity[0u], 'c');
  1438. registry.emplace<char>(entity[2u], 'c');
  1439. std::size_t cnt{};
  1440. group.each([&cnt](auto...) { ++cnt; });
  1441. ASSERT_TRUE((registry.owned<int, char>()));
  1442. ASSERT_TRUE(registry.owned<int>());
  1443. ASSERT_FALSE(registry.owned<char>());
  1444. ASSERT_EQ(cnt, 2u);
  1445. }
  1446. TEST(Registry, CleanNonOwningGroupViewAfterRemoveAndClear) {
  1447. entt::registry registry{};
  1448. auto group = registry.group(entt::get<int, char>);
  1449. const auto entity = registry.create();
  1450. registry.emplace<int>(entity, 0);
  1451. registry.emplace<char>(entity, 'c');
  1452. ASSERT_EQ(group.size(), 1u);
  1453. registry.erase<char>(entity);
  1454. ASSERT_EQ(group.size(), 0u);
  1455. registry.emplace<char>(entity, 'c');
  1456. ASSERT_EQ(group.size(), 1u);
  1457. registry.clear<int>();
  1458. ASSERT_EQ(group.size(), 0u);
  1459. registry.emplace<int>(entity, 0);
  1460. ASSERT_EQ(group.size(), 1u);
  1461. registry.clear();
  1462. ASSERT_EQ(group.size(), 0u);
  1463. }
  1464. TEST(Registry, CleanFullOwningGroupViewAfterRemoveAndClear) {
  1465. entt::registry registry{};
  1466. auto group = registry.group<int, char>();
  1467. const auto entity = registry.create();
  1468. registry.emplace<int>(entity, 0);
  1469. registry.emplace<char>(entity, 'c');
  1470. ASSERT_EQ(group.size(), 1u);
  1471. registry.erase<char>(entity);
  1472. ASSERT_EQ(group.size(), 0u);
  1473. registry.emplace<char>(entity, 'c');
  1474. ASSERT_EQ(group.size(), 1u);
  1475. registry.clear<int>();
  1476. ASSERT_EQ(group.size(), 0u);
  1477. registry.emplace<int>(entity, 0);
  1478. ASSERT_EQ(group.size(), 1u);
  1479. registry.clear();
  1480. ASSERT_EQ(group.size(), 0u);
  1481. }
  1482. TEST(Registry, CleanPartialOwningGroupViewAfterRemoveAndClear) {
  1483. entt::registry registry{};
  1484. auto group = registry.group<int>(entt::get<char>);
  1485. const auto entity = registry.create();
  1486. registry.emplace<int>(entity, 0);
  1487. registry.emplace<char>(entity, 'c');
  1488. ASSERT_EQ(group.size(), 1u);
  1489. registry.erase<char>(entity);
  1490. ASSERT_EQ(group.size(), 0u);
  1491. registry.emplace<char>(entity, 'c');
  1492. ASSERT_EQ(group.size(), 1u);
  1493. registry.clear<int>();
  1494. ASSERT_EQ(group.size(), 0u);
  1495. registry.emplace<int>(entity, 0);
  1496. ASSERT_EQ(group.size(), 1u);
  1497. registry.clear();
  1498. ASSERT_EQ(group.size(), 0u);
  1499. }
  1500. ENTT_DEBUG_TEST(RegistryDeathTest, NestedGroups) {
  1501. entt::registry registry{};
  1502. registry.group<int, double>(entt::get<char>);
  1503. ASSERT_DEATH(registry.group<int>(entt::get<char>), "");
  1504. ASSERT_DEATH(registry.group<int>(entt::get<char, double>), "");
  1505. ASSERT_DEATH(registry.group<int>(entt::get<char>, entt::exclude<double>), "");
  1506. ASSERT_DEATH((registry.group<int, double>()), "");
  1507. }
  1508. ENTT_DEBUG_TEST(RegistryDeathTest, ConflictingGroups) {
  1509. entt::registry registry{};
  1510. registry.group<char>(entt::get<int>, entt::exclude<double>);
  1511. ASSERT_DEATH(registry.group<char>(entt::get<float>, entt::exclude<double>), "");
  1512. }
  1513. TEST(Registry, GroupIfExists) {
  1514. entt::registry registry{};
  1515. const auto entity = registry.create();
  1516. auto group = std::as_const(registry).group_if_exists<int>(entt::get<char>, entt::exclude<double>);
  1517. ASSERT_FALSE(group);
  1518. ASSERT_EQ(std::as_const(registry).storage<int>(), nullptr);
  1519. ASSERT_EQ(std::as_const(registry).storage<char>(), nullptr);
  1520. ASSERT_EQ(std::as_const(registry).storage<double>(), nullptr);
  1521. registry.emplace<int>(entity);
  1522. group = std::as_const(registry).group_if_exists<int>(entt::get<char>, entt::exclude<double>);
  1523. ASSERT_FALSE(group);
  1524. registry.emplace<char>(entity);
  1525. group = std::as_const(registry).group_if_exists<int>(entt::get<char>, entt::exclude<double>);
  1526. ASSERT_FALSE(group);
  1527. registry.emplace<double>(entity);
  1528. group = std::as_const(registry).group_if_exists<int>(entt::get<char>, entt::exclude<double>);
  1529. ASSERT_FALSE(group);
  1530. registry.group<int>(entt::get<char>, entt::exclude<double>);
  1531. group = std::as_const(registry).group_if_exists<int>(entt::get<char>, entt::exclude<double>);
  1532. ASSERT_TRUE(group);
  1533. }
  1534. TEST(Registry, SortSingle) {
  1535. entt::registry registry{};
  1536. int val = 0;
  1537. registry.emplace<int>(registry.create(), val++);
  1538. registry.emplace<int>(registry.create(), val++);
  1539. registry.emplace<int>(registry.create(), val++);
  1540. for(auto entity: registry.view<int>()) {
  1541. ASSERT_EQ(registry.get<int>(entity), --val);
  1542. }
  1543. registry.sort<int>(std::less{});
  1544. for(auto entity: registry.view<int>()) {
  1545. ASSERT_EQ(registry.get<int>(entity), val++);
  1546. }
  1547. }
  1548. TEST(Registry, SortMulti) {
  1549. entt::registry registry{};
  1550. unsigned int uval = 0u;
  1551. int ival = 0;
  1552. for(auto i = 0; i < 3; ++i) {
  1553. const auto entity = registry.create();
  1554. registry.emplace<unsigned int>(entity, uval++);
  1555. registry.emplace<int>(entity, ival++);
  1556. }
  1557. for(auto entity: registry.view<unsigned int>()) {
  1558. ASSERT_EQ(registry.get<unsigned int>(entity), --uval);
  1559. }
  1560. for(auto entity: registry.view<int>()) {
  1561. ASSERT_EQ(registry.get<int>(entity), --ival);
  1562. }
  1563. registry.sort<unsigned int>(std::less{});
  1564. registry.sort<int, unsigned int>();
  1565. for(auto entity: registry.view<unsigned int>()) {
  1566. ASSERT_EQ(registry.get<unsigned int>(entity), uval++);
  1567. }
  1568. for(auto entity: registry.view<int>()) {
  1569. ASSERT_EQ(registry.get<int>(entity), ival++);
  1570. }
  1571. }
  1572. TEST(Registry, SortEmpty) {
  1573. entt::registry registry{};
  1574. registry.emplace<test::empty>(registry.create());
  1575. registry.emplace<test::empty>(registry.create());
  1576. registry.emplace<test::empty>(registry.create());
  1577. ASSERT_LT(registry.storage<test::empty>().data()[0], registry.storage<test::empty>().data()[1]);
  1578. ASSERT_LT(registry.storage<test::empty>().data()[1], registry.storage<test::empty>().data()[2]);
  1579. registry.sort<test::empty>(std::less{});
  1580. ASSERT_GT(registry.storage<test::empty>().data()[0], registry.storage<test::empty>().data()[1]);
  1581. ASSERT_GT(registry.storage<test::empty>().data()[1], registry.storage<test::empty>().data()[2]);
  1582. }
  1583. TEST(Registry, Context) {
  1584. entt::registry registry{};
  1585. auto &ctx = registry.ctx();
  1586. const auto &cctx = std::as_const(registry).ctx();
  1587. ASSERT_FALSE(ctx.contains<char>());
  1588. ASSERT_FALSE(cctx.contains<const int>());
  1589. ASSERT_EQ(ctx.find<char>(), nullptr);
  1590. ASSERT_EQ(cctx.find<const int>(), nullptr);
  1591. ctx.emplace<char>();
  1592. ctx.emplace<int>();
  1593. ASSERT_TRUE(ctx.contains<char>());
  1594. ASSERT_TRUE(cctx.contains<int>());
  1595. ASSERT_NE(ctx.find<const char>(), nullptr);
  1596. ASSERT_NE(cctx.find<const int>(), nullptr);
  1597. ASSERT_FALSE(ctx.erase<double>());
  1598. ASSERT_TRUE(ctx.erase<int>());
  1599. ASSERT_TRUE(ctx.contains<const char>());
  1600. ASSERT_FALSE(cctx.contains<const int>());
  1601. ASSERT_NE(ctx.find<char>(), nullptr);
  1602. ASSERT_EQ(cctx.find<int>(), nullptr);
  1603. ASSERT_FALSE(ctx.erase<int>());
  1604. ASSERT_TRUE(ctx.erase<char>());
  1605. ctx.emplace<char>('c');
  1606. ctx.emplace<int>(1);
  1607. ASSERT_EQ(ctx.emplace<char>('a'), 'c');
  1608. ASSERT_EQ(ctx.find<const char>(), cctx.find<char>());
  1609. ASSERT_EQ(ctx.get<char>(), cctx.get<const char>());
  1610. ASSERT_EQ(ctx.get<char>(), 'c');
  1611. ASSERT_EQ(ctx.emplace<const int>(0), 1);
  1612. ASSERT_EQ(ctx.find<const int>(), cctx.find<int>());
  1613. ASSERT_EQ(ctx.get<int>(), cctx.get<const int>());
  1614. ASSERT_EQ(ctx.get<int>(), 1);
  1615. ASSERT_EQ(ctx.find<double>(), nullptr);
  1616. ASSERT_EQ(cctx.find<double>(), nullptr);
  1617. ASSERT_EQ(ctx.insert_or_assign<char>('a'), 'a');
  1618. ASSERT_EQ(ctx.find<const char>(), cctx.find<char>());
  1619. ASSERT_EQ(ctx.get<char>(), cctx.get<const char>());
  1620. ASSERT_EQ(ctx.get<const char>(), 'a');
  1621. ASSERT_EQ(ctx.insert_or_assign<const int>(0), 0);
  1622. ASSERT_EQ(ctx.find<const int>(), cctx.find<int>());
  1623. ASSERT_EQ(ctx.get<int>(), cctx.get<const int>());
  1624. ASSERT_EQ(ctx.get<int>(), 0);
  1625. }
  1626. TEST(Registry, ContextHint) {
  1627. using namespace entt::literals;
  1628. entt::registry registry{};
  1629. auto &ctx = registry.ctx();
  1630. const auto &cctx = std::as_const(registry).ctx();
  1631. ctx.emplace<int>(1);
  1632. ctx.emplace_as<int>("other"_hs, 3);
  1633. ASSERT_TRUE(ctx.contains<int>());
  1634. ASSERT_TRUE(cctx.contains<const int>("other"_hs));
  1635. ASSERT_FALSE(ctx.contains<char>("other"_hs));
  1636. ASSERT_NE(cctx.find<const int>(), nullptr);
  1637. ASSERT_NE(ctx.find<int>("other"_hs), nullptr);
  1638. ASSERT_EQ(cctx.find<const char>("other"_hs), nullptr);
  1639. ASSERT_EQ(ctx.get<int>(), 1);
  1640. ASSERT_EQ(cctx.get<const int>("other"_hs), 3);
  1641. ctx.insert_or_assign(3);
  1642. ctx.insert_or_assign("other"_hs, 1);
  1643. ASSERT_EQ(ctx.get<const int>(), 3);
  1644. ASSERT_EQ(cctx.get<int>("other"_hs), 1);
  1645. ASSERT_FALSE(ctx.erase<char>("other"_hs));
  1646. ASSERT_TRUE(ctx.erase<int>());
  1647. ASSERT_TRUE(cctx.contains<int>("other"_hs));
  1648. ASSERT_EQ(ctx.get<int>("other"_hs), 1);
  1649. ASSERT_TRUE(ctx.erase<int>("other"_hs));
  1650. ASSERT_FALSE(cctx.contains<int>("other"_hs));
  1651. ASSERT_EQ(ctx.find<int>("other"_hs), nullptr);
  1652. }
  1653. TEST(Registry, ContextAsRef) {
  1654. entt::registry registry{};
  1655. int value{3};
  1656. registry.ctx().emplace<int &>(value);
  1657. ASSERT_NE(registry.ctx().find<int>(), nullptr);
  1658. ASSERT_NE(registry.ctx().find<const int>(), nullptr);
  1659. ASSERT_NE(std::as_const(registry).ctx().find<const int>(), nullptr);
  1660. ASSERT_EQ(registry.ctx().get<const int>(), value);
  1661. ASSERT_EQ(registry.ctx().get<int>(), value);
  1662. registry.ctx().get<int>() = 2;
  1663. ASSERT_EQ(value, 2);
  1664. ASSERT_EQ(registry.ctx().get<int>(), value);
  1665. value = 1;
  1666. ASSERT_EQ(std::as_const(registry).ctx().get<const int>(), value);
  1667. }
  1668. TEST(Registry, ContextAsConstRef) {
  1669. entt::registry registry{};
  1670. int value{3};
  1671. registry.ctx().emplace<const int &>(value);
  1672. ASSERT_EQ(registry.ctx().find<int>(), nullptr);
  1673. ASSERT_NE(registry.ctx().find<const int>(), nullptr);
  1674. ASSERT_NE(std::as_const(registry).ctx().find<const int>(), nullptr);
  1675. ASSERT_EQ(registry.ctx().get<const int>(), value);
  1676. value = 1;
  1677. ASSERT_EQ(std::as_const(registry).ctx().get<const int>(), value);
  1678. }
  1679. TEST(Registry, ContextPoolMemberDestructionOrder) {
  1680. auto registry = std::make_unique<entt::registry>();
  1681. const auto entity = registry->create();
  1682. bool ctx_check = false;
  1683. registry->ctx().emplace<typename destruction_order::ctx_check_type>();
  1684. registry->emplace<destruction_order>(entity, *registry, ctx_check);
  1685. registry.reset();
  1686. ASSERT_TRUE(ctx_check);
  1687. }
  1688. TEST(Registry, Constness) {
  1689. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().emplace<int>({})), int &>();
  1690. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().emplace<test::empty>({})), void>();
  1691. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().get<>({})), std::tuple<>>();
  1692. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().get<int>({})), int &>();
  1693. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().get<int, const char>({})), std::tuple<int &, const char &>>();
  1694. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().try_get<>({})), std::tuple<>>();
  1695. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().try_get<int>({})), int *>();
  1696. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().try_get<int, const char>({})), std::tuple<int *, const char *>>();
  1697. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().ctx().get<int>()), int &>();
  1698. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().ctx().get<const char>()), const char &>();
  1699. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().ctx().find<int>()), int *>();
  1700. testing::StaticAssertTypeEq<decltype(std::declval<entt::registry>().ctx().find<const char>()), const char *>();
  1701. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().get<>({})), std::tuple<>>();
  1702. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().get<int>({})), const int &>();
  1703. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().get<int, const char>({})), std::tuple<const int &, const char &>>();
  1704. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().try_get<>({})), std::tuple<>>();
  1705. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().try_get<int>({})), const int *>();
  1706. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().try_get<int, const char>({})), std::tuple<const int *, const char *>>();
  1707. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().ctx().get<int>()), const int &>();
  1708. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().ctx().get<const char>()), const char &>();
  1709. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().ctx().find<int>()), const int *>();
  1710. testing::StaticAssertTypeEq<decltype(std::declval<const entt::registry>().ctx().find<const char>()), const char *>();
  1711. }
  1712. TEST(Registry, AssignEntities) {
  1713. using traits_type = entt::entt_traits<entt::entity>;
  1714. entt::registry registry{};
  1715. std::array<entt::entity, 3u> entity{};
  1716. registry.create(entity.begin(), entity.end());
  1717. registry.destroy(entity[1]);
  1718. registry.destroy(entity[2]);
  1719. entt::registry other{};
  1720. auto &src = registry.storage<entt::entity>();
  1721. auto &dst = other.storage<entt::entity>();
  1722. dst.push(src.rbegin(), src.rend());
  1723. dst.free_list(src.free_list());
  1724. ASSERT_EQ(registry.storage<entt::entity>().size(), other.storage<entt::entity>().size());
  1725. ASSERT_TRUE(other.valid(entity[0]));
  1726. ASSERT_FALSE(other.valid(entity[1]));
  1727. ASSERT_FALSE(other.valid(entity[2]));
  1728. ASSERT_EQ(registry.create(), other.create());
  1729. ASSERT_EQ(traits_type::to_entity(other.create()), traits_type::to_integral(entity[1]));
  1730. }
  1731. TEST(Registry, ScramblingPoolsIsAllowed) {
  1732. entt::registry registry{};
  1733. registry.on_destroy<int>().connect<&listener::sort<int>>();
  1734. for(std::size_t i{}; i < 2u; ++i) {
  1735. const auto entity = registry.create();
  1736. registry.emplace<int>(entity, static_cast<int>(i));
  1737. }
  1738. registry.destroy(registry.view<int>().back());
  1739. // thanks to @andranik3949 for pointing out this missing test
  1740. registry.view<const int>().each([](const auto entity, const auto &value) {
  1741. ASSERT_EQ(static_cast<int>(entt::to_integral(entity)), value);
  1742. });
  1743. }
  1744. TEST(Registry, AssureMixinLoop) {
  1745. entt::registry registry{};
  1746. const auto entity = registry.create();
  1747. ASSERT_EQ(std::as_const(registry).storage<test::assure_loop>(), nullptr);
  1748. ASSERT_EQ(std::as_const(registry).storage<int>(), nullptr);
  1749. registry.emplace<test::assure_loop>(entity);
  1750. ASSERT_NE(std::as_const(registry).storage<test::assure_loop>(), nullptr);
  1751. ASSERT_NE(std::as_const(registry).storage<int>(), nullptr);
  1752. ASSERT_TRUE(registry.all_of<test::assure_loop>(entity));
  1753. ASSERT_FALSE(registry.all_of<int>(entity));
  1754. }
  1755. TEST(Registry, VoidType) {
  1756. using namespace entt::literals;
  1757. entt::registry registry{};
  1758. const auto entity = registry.create();
  1759. auto &storage = registry.storage<void>("custom"_hs);
  1760. storage.emplace(entity);
  1761. ASSERT_TRUE(registry.storage<void>().empty());
  1762. ASSERT_FALSE(registry.storage<void>("custom"_hs).empty());
  1763. ASSERT_TRUE(registry.storage<void>("custom"_hs).contains(entity));
  1764. ASSERT_EQ(registry.storage<void>().type(), entt::type_id<void>());
  1765. ASSERT_EQ(registry.storage<void>("custom"_hs).type(), entt::type_id<void>());
  1766. }
  1767. TEST(Registry, NoEtoType) {
  1768. entt::registry registry{};
  1769. const auto entity = registry.create();
  1770. registry.emplace<no_eto_type>(entity);
  1771. registry.emplace<int>(entity, 1);
  1772. ASSERT_NE(registry.storage<no_eto_type>().raw(), nullptr);
  1773. ASSERT_NE(registry.try_get<no_eto_type>(entity), nullptr);
  1774. ASSERT_EQ(registry.view<no_eto_type>().get(entity), std::as_const(registry).view<const no_eto_type>().get(entity));
  1775. auto view = registry.view<no_eto_type, int>();
  1776. auto cview = std::as_const(registry).view<const no_eto_type, const int>();
  1777. ASSERT_EQ((std::get<0>(view.get<no_eto_type, int>(entity))), (std::get<0>(cview.get<const no_eto_type, const int>(entity))));
  1778. }