ServerHierarchyTests.cpp 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <CommonHierarchySetup.h>
  8. #include <MockInterfaces.h>
  9. #include <AzCore/Component/Entity.h>
  10. #include <AzCore/Console/Console.h>
  11. #include <AzCore/Name/Name.h>
  12. #include <AzCore/Serialization/SerializeContext.h>
  13. #include <AzCore/UnitTest/TestTypes.h>
  14. #include <AzCore/UnitTest/UnitTest.h>
  15. #include <AzFramework/Components/TransformComponent.h>
  16. #include <AzNetworking/Serialization/StringifySerializer.h>
  17. #include <AzTest/AzTest.h>
  18. #include <Multiplayer/Components/NetBindComponent.h>
  19. #include <Multiplayer/Components/NetworkHierarchyChildComponent.h>
  20. #include <Multiplayer/Components/NetworkHierarchyRootComponent.h>
  21. #include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
  22. namespace Multiplayer
  23. {
  24. using namespace testing;
  25. using namespace ::UnitTest;
  26. /*
  27. * Parent -> Child
  28. */
  29. class ServerSimpleHierarchyTests : public HierarchyTests
  30. {
  31. public:
  32. void SetUp() override
  33. {
  34. HierarchyTests::SetUp();
  35. m_root = AZStd::make_unique<EntityInfo>(1, "root", NetEntityId{ 1 }, EntityInfo::Role::Root);
  36. m_child = AZStd::make_unique<EntityInfo>(2, "child", NetEntityId{ 2 }, EntityInfo::Role::Child);
  37. CreateSimpleHierarchy(*m_root, *m_child);
  38. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  39. // now the two entities are under one hierarchy
  40. }
  41. void TearDown() override
  42. {
  43. m_child.reset();
  44. m_root.reset();
  45. HierarchyTests::TearDown();
  46. }
  47. void CreateSimpleHierarchy(EntityInfo& root, EntityInfo& child)
  48. {
  49. PopulateHierarchicalEntity(root);
  50. SetupEntity(root.m_entity, root.m_netId, NetEntityRole::Authority);
  51. PopulateHierarchicalEntity(child);
  52. SetupEntity(child.m_entity, child.m_netId, NetEntityRole::Authority);
  53. // Create an entity replicator for the child entity
  54. const NetworkEntityHandle childHandle(child.m_entity.get(), m_networkEntityTracker.get());
  55. child.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childHandle);
  56. child.m_replicator->Initialize(childHandle);
  57. // Create an entity replicator for the root entity
  58. const NetworkEntityHandle rootHandle(root.m_entity.get(), m_networkEntityTracker.get());
  59. root.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, rootHandle);
  60. root.m_replicator->Initialize(rootHandle);
  61. root.m_entity->Activate();
  62. child.m_entity->Activate();
  63. }
  64. AZStd::unique_ptr<EntityInfo> m_root;
  65. AZStd::unique_ptr<EntityInfo> m_child;
  66. };
  67. TEST_F(ServerSimpleHierarchyTests, Server_Sets_Appropriate_Network_Fields_For_Clients)
  68. {
  69. EXPECT_EQ(
  70. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchyRoot(),
  71. InvalidNetEntityId
  72. );
  73. EXPECT_EQ(
  74. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  75. NetEntityId{ 1 }
  76. );
  77. }
  78. TEST_F(ServerSimpleHierarchyTests, Root_Is_Top_Level_Root)
  79. {
  80. EXPECT_EQ(
  81. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  82. false
  83. );
  84. }
  85. TEST_F(ServerSimpleHierarchyTests, Child_Has_Root_Set)
  86. {
  87. EXPECT_EQ(
  88. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  89. NetEntityId{ 1 }
  90. );
  91. }
  92. TEST_F(ServerSimpleHierarchyTests, Child_Has_Root_Cleared_On_Detach)
  93. {
  94. // now detach the child
  95. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  96. EXPECT_EQ(
  97. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  98. InvalidNetEntityId
  99. );
  100. }
  101. TEST_F(ServerSimpleHierarchyTests, Root_Has_Child_Reference)
  102. {
  103. EXPECT_EQ(
  104. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  105. 2
  106. );
  107. }
  108. TEST_F(ServerSimpleHierarchyTests, Root_Has_Child_References_Removed_On_Detach)
  109. {
  110. // now detach the child
  111. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  112. EXPECT_EQ(
  113. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  114. 1
  115. );
  116. }
  117. TEST_F(ServerSimpleHierarchyTests, Root_Deactivates_Child_Has_No_References_To_Root)
  118. {
  119. StopEntity(m_root->m_entity);
  120. m_root->m_entity->Deactivate();
  121. m_root->m_entity.reset();
  122. EXPECT_EQ(
  123. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  124. InvalidNetEntityId
  125. );
  126. }
  127. TEST_F(ServerSimpleHierarchyTests, Child_Deactivates_Root_Has_No_References_To_Child)
  128. {
  129. m_child.reset();
  130. EXPECT_EQ(
  131. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  132. 1
  133. );
  134. }
  135. TEST_F(ServerSimpleHierarchyTests, Root_Deactivates_IsHierarchyEnabled_Is_False)
  136. {
  137. EXPECT_EQ(
  138. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchyEnabled(),
  139. true
  140. );
  141. StopEntity(m_root->m_entity);
  142. m_root->m_entity->Deactivate();
  143. EXPECT_EQ(
  144. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchyEnabled(),
  145. false
  146. );
  147. m_root->m_entity.reset();
  148. }
  149. TEST_F(ServerSimpleHierarchyTests, Child_Deactivates_IsHierarchyEnabled_Is_False)
  150. {
  151. EXPECT_EQ(
  152. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->IsHierarchyEnabled(),
  153. true
  154. );
  155. StopEntity(m_child->m_entity);
  156. m_child->m_entity->Deactivate();
  157. EXPECT_EQ(
  158. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->IsHierarchyEnabled(),
  159. false
  160. );
  161. m_child->m_entity.reset();
  162. }
  163. TEST_F(ServerSimpleHierarchyTests, ChildPointsToRootAfterReattachment)
  164. {
  165. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  166. EXPECT_EQ(
  167. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  168. InvalidNetEntityId
  169. );
  170. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  171. EXPECT_EQ(
  172. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  173. m_root->m_entity->FindComponent<NetBindComponent>()->GetNetEntityId()
  174. );
  175. }
  176. TEST_F(ServerSimpleHierarchyTests, ChildHasOwningConnectionIdOfParent)
  177. {
  178. // disconnect and assign new connection ids
  179. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  180. m_root->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 1 });
  181. m_child->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 2 });
  182. const ConnectionId previousConnectionId = m_child->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId();
  183. // re-attach, child's owning connection id should then be root's connection id
  184. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  185. EXPECT_EQ(
  186. m_child->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  187. m_root->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  188. );
  189. // detach, the child should roll back to his previous owning connection id
  190. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  191. EXPECT_EQ(
  192. m_child->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  193. previousConnectionId
  194. );
  195. }
  196. /*
  197. * Parent -> Child -> ChildOfChild
  198. */
  199. class ServerDeepHierarchyTests : public HierarchyTests
  200. {
  201. public:
  202. const NetEntityId RootNetEntityId = NetEntityId{ 1 };
  203. const NetEntityId ChildNetEntityId = NetEntityId{ 2 };
  204. const NetEntityId ChildOfChildNetEntityId = NetEntityId{ 3 };
  205. void SetUp() override
  206. {
  207. HierarchyTests::SetUp();
  208. m_root = AZStd::make_unique<EntityInfo>((1), "root", RootNetEntityId, EntityInfo::Role::Root);
  209. m_child = AZStd::make_unique<EntityInfo>((2), "child", ChildNetEntityId, EntityInfo::Role::Child);
  210. m_childOfChild = AZStd::make_unique<EntityInfo>((3), "child of child", ChildOfChildNetEntityId, EntityInfo::Role::Child);
  211. CreateDeepHierarchy(*m_root, *m_child, *m_childOfChild);
  212. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  213. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child->m_entity->GetId());
  214. // now the entities are under one hierarchy
  215. }
  216. void TearDown() override
  217. {
  218. m_childOfChild.reset();
  219. m_child.reset();
  220. m_root.reset();
  221. HierarchyTests::TearDown();
  222. }
  223. AZStd::unique_ptr<EntityInfo> m_root;
  224. AZStd::unique_ptr<EntityInfo> m_child;
  225. AZStd::unique_ptr<EntityInfo> m_childOfChild;
  226. };
  227. TEST_F(ServerDeepHierarchyTests, Root_Is_Top_Level_Root)
  228. {
  229. EXPECT_EQ(
  230. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  231. false
  232. );
  233. }
  234. TEST_F(ServerDeepHierarchyTests, Root_Has_Child_References)
  235. {
  236. EXPECT_EQ(
  237. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  238. 3
  239. );
  240. if (m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 3)
  241. {
  242. EXPECT_EQ(
  243. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  244. m_root->m_entity.get()
  245. );
  246. EXPECT_EQ(
  247. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  248. m_child->m_entity.get()
  249. );
  250. EXPECT_EQ(
  251. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  252. m_childOfChild->m_entity.get()
  253. );
  254. EXPECT_EQ(
  255. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchicalEntities()[2],
  256. m_childOfChild->m_entity.get()
  257. );
  258. }
  259. }
  260. TEST_F(ServerDeepHierarchyTests, Root_Has_Child_Of_Child_Reference_Removed_On_Detach)
  261. {
  262. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  263. EXPECT_EQ(
  264. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  265. 2
  266. );
  267. }
  268. TEST_F(ServerDeepHierarchyTests, Root_Has_All_References_Removed_On_Detach_Of_Mid_Child)
  269. {
  270. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  271. EXPECT_EQ(
  272. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  273. 1
  274. );
  275. }
  276. TEST_F(ServerDeepHierarchyTests, Root_Has_All_References_If_Mid_Child_Added_With_Child)
  277. {
  278. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  279. // reconnect
  280. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  281. EXPECT_EQ(
  282. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  283. 3
  284. );
  285. }
  286. TEST_F(ServerDeepHierarchyTests, Root_Has_All_References_If_Child_Of_Child_Added)
  287. {
  288. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  289. // reconnect
  290. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  291. EXPECT_EQ(
  292. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  293. 3
  294. );
  295. }
  296. TEST_F(ServerDeepHierarchyTests, Child_Of_Child_Points_To_Root_After_Attach)
  297. {
  298. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  299. // reconnect
  300. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  301. EXPECT_EQ(
  302. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  303. RootNetEntityId
  304. );
  305. }
  306. TEST_F(ServerDeepHierarchyTests, All_New_Children_Point_To_Root_If_Mid_Child_Added_With_Child)
  307. {
  308. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  309. // reconnect
  310. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  311. EXPECT_EQ(
  312. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  313. RootNetEntityId
  314. );
  315. EXPECT_EQ(
  316. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  317. RootNetEntityId
  318. );
  319. }
  320. TEST_F(ServerDeepHierarchyTests, Children_Clear_Reference_To_Root_After_Mid_Child_Detached)
  321. {
  322. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  323. EXPECT_EQ(
  324. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  325. InvalidNetEntityId
  326. );
  327. EXPECT_EQ(
  328. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  329. InvalidNetEntityId
  330. );
  331. }
  332. TEST_F(ServerDeepHierarchyTests, Child_Of_Child_Clears_Reference_To_Root_After_Detached)
  333. {
  334. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  335. EXPECT_EQ(
  336. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  337. InvalidNetEntityId
  338. );
  339. }
  340. TEST_F(ServerDeepHierarchyTests, Root_Deactivates_Children_Have_No_References_To_Root)
  341. {
  342. m_root.reset();
  343. EXPECT_EQ(
  344. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  345. InvalidNetEntityId
  346. );
  347. EXPECT_EQ(
  348. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  349. InvalidNetEntityId
  350. );
  351. }
  352. TEST_F(ServerDeepHierarchyTests, Child_Of_Child_Deactivates_Root_Removes_References_To_It)
  353. {
  354. m_childOfChild.reset();
  355. EXPECT_EQ(
  356. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  357. 2
  358. );
  359. }
  360. TEST_F(ServerDeepHierarchyTests, Testing_Limiting_Hierarchy_Maximum_Size)
  361. {
  362. uint32_t currentMaxLimit = 0;
  363. m_console->GetCvarValue<uint32_t>("bg_hierarchyEntityMaxLimit", currentMaxLimit);
  364. m_console->PerformCommand("bg_hierarchyEntityMaxLimit 2");
  365. // remake the hierarchy
  366. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  367. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  368. EXPECT_EQ(
  369. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  370. 2
  371. );
  372. m_console->PerformCommand((AZStd::string("bg_hierarchyEntityMaxLimit ") + AZStd::to_string(currentMaxLimit)).c_str());
  373. m_console->GetCvarValue<uint32_t>("bg_hierarchyEntityMaxLimit", currentMaxLimit);
  374. }
  375. TEST_F(ServerDeepHierarchyTests, ReattachMiddleChildRebuildInvokedTwice)
  376. {
  377. MockNetworkHierarchyCallbackHandler mock;
  378. EXPECT_CALL(mock, OnNetworkHierarchyUpdated(m_root->m_entity->GetId())).Times(2);
  379. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->BindNetworkHierarchyChangedEventHandler(mock.m_changedHandler);
  380. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  381. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  382. }
  383. TEST_F(ServerDeepHierarchyTests, SerializeHierarchyCorrection)
  384. {
  385. AzNetworking::StringifySerializer serializer;
  386. EXPECT_TRUE(m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->SerializeEntityCorrection(serializer));
  387. }
  388. /*
  389. * Parent -> Child -> Child Of Child
  390. * -> Child2 -> Child Of Child2
  391. * -> Child2 Of Child2
  392. */
  393. class ServerBranchedHierarchyTests : public HierarchyTests
  394. {
  395. public:
  396. const NetEntityId RootNetEntityId = NetEntityId{ 1 };
  397. const NetEntityId ChildNetEntityId = NetEntityId{ 2 };
  398. const NetEntityId ChildOfChildNetEntityId = NetEntityId{ 3 };
  399. const NetEntityId Child2NetEntityId = NetEntityId{ 4 };
  400. const NetEntityId ChildOfChild2NetEntityId = NetEntityId{ 5 };
  401. const NetEntityId Child2OfChild2NetEntityId = NetEntityId{ 6 };
  402. void SetUp() override
  403. {
  404. HierarchyTests::SetUp();
  405. m_root = AZStd::make_unique<EntityInfo>((1), "root", RootNetEntityId, EntityInfo::Role::Root);
  406. m_child = AZStd::make_unique<EntityInfo>((2), "child", ChildNetEntityId, EntityInfo::Role::Child);
  407. m_childOfChild = AZStd::make_unique<EntityInfo>((3), "child of child", ChildOfChildNetEntityId, EntityInfo::Role::Child);
  408. m_child2 = AZStd::make_unique<EntityInfo>((4), "child2", Child2NetEntityId, EntityInfo::Role::Child);
  409. m_childOfChild2 = AZStd::make_unique<EntityInfo>((5), "child of child2", ChildOfChild2NetEntityId, EntityInfo::Role::Child);
  410. m_child2OfChild2 = AZStd::make_unique<EntityInfo>((6), "child2 of child2", Child2OfChild2NetEntityId, EntityInfo::Role::Child);
  411. CreateBranchedHierarchy(*m_root, *m_child, *m_childOfChild,
  412. *m_child2, *m_childOfChild2, *m_child2OfChild2);
  413. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  414. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  415. m_child2OfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  416. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  417. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child->m_entity->GetId());
  418. // now the entities are under one hierarchy
  419. }
  420. void TearDown() override
  421. {
  422. m_child2OfChild2.reset();
  423. m_childOfChild2.reset();
  424. m_child2.reset();
  425. m_childOfChild.reset();
  426. m_child.reset();
  427. m_root.reset();
  428. HierarchyTests::TearDown();
  429. }
  430. void CreateBranchedHierarchy(EntityInfo& root, EntityInfo& child, EntityInfo& childOfChild,
  431. EntityInfo& child2, EntityInfo& childOfChild2, EntityInfo& child2OfChild2)
  432. {
  433. PopulateHierarchicalEntity(root);
  434. PopulateHierarchicalEntity(child);
  435. PopulateHierarchicalEntity(childOfChild);
  436. PopulateHierarchicalEntity(child2);
  437. PopulateHierarchicalEntity(childOfChild2);
  438. PopulateHierarchicalEntity(child2OfChild2);
  439. SetupEntity(root.m_entity, root.m_netId, NetEntityRole::Authority);
  440. SetupEntity(child.m_entity, child.m_netId, NetEntityRole::Authority);
  441. SetupEntity(childOfChild.m_entity, childOfChild.m_netId, NetEntityRole::Authority);
  442. SetupEntity(child2.m_entity, child2.m_netId, NetEntityRole::Authority);
  443. SetupEntity(childOfChild2.m_entity, childOfChild2.m_netId, NetEntityRole::Authority);
  444. SetupEntity(child2OfChild2.m_entity, child2OfChild2.m_netId, NetEntityRole::Authority);
  445. // Create entity replicators
  446. const NetworkEntityHandle childOfChild2Handle(childOfChild2.m_entity.get(), m_networkEntityTracker.get());
  447. childOfChild.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childOfChild2Handle);
  448. childOfChild.m_replicator->Initialize(childOfChild2Handle);
  449. const NetworkEntityHandle child2OfChild2Handle(child2OfChild2.m_entity.get(), m_networkEntityTracker.get());
  450. childOfChild.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, child2OfChild2Handle);
  451. childOfChild.m_replicator->Initialize(child2OfChild2Handle);
  452. const NetworkEntityHandle child2Handle(child2.m_entity.get(), m_networkEntityTracker.get());
  453. child.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, child2Handle);
  454. child.m_replicator->Initialize(child2Handle);
  455. const NetworkEntityHandle childOfChildHandle(childOfChild.m_entity.get(), m_networkEntityTracker.get());
  456. childOfChild.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childOfChildHandle);
  457. childOfChild.m_replicator->Initialize(childOfChildHandle);
  458. const NetworkEntityHandle childHandle(child.m_entity.get(), m_networkEntityTracker.get());
  459. child.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, childHandle);
  460. child.m_replicator->Initialize(childHandle);
  461. const NetworkEntityHandle rootHandle(root.m_entity.get(), m_networkEntityTracker.get());
  462. root.m_replicator = AZStd::make_unique<EntityReplicator>(*m_entityReplicationManager, m_mockConnection.get(), NetEntityRole::Client, rootHandle);
  463. root.m_replicator->Initialize(rootHandle);
  464. root.m_entity->Activate();
  465. child.m_entity->Activate();
  466. childOfChild.m_entity->Activate();
  467. child2.m_entity->Activate();
  468. childOfChild2.m_entity->Activate();
  469. child2OfChild2.m_entity->Activate();
  470. }
  471. AZStd::unique_ptr<EntityInfo> m_root;
  472. AZStd::unique_ptr<EntityInfo> m_child;
  473. AZStd::unique_ptr<EntityInfo> m_childOfChild;
  474. AZStd::unique_ptr<EntityInfo> m_child2;
  475. AZStd::unique_ptr<EntityInfo> m_childOfChild2;
  476. AZStd::unique_ptr<EntityInfo> m_child2OfChild2;
  477. };
  478. TEST_F(ServerBranchedHierarchyTests, Sanity_Check)
  479. {
  480. EXPECT_EQ(
  481. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  482. 6
  483. );
  484. if (m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 6)
  485. {
  486. EXPECT_EQ(
  487. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  488. m_root->m_entity.get()
  489. );
  490. EXPECT_EQ(
  491. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  492. m_child->m_entity.get()
  493. );
  494. EXPECT_EQ(
  495. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  496. m_child2->m_entity.get()
  497. );
  498. EXPECT_EQ(
  499. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[3],
  500. m_childOfChild->m_entity.get()
  501. );
  502. EXPECT_EQ(
  503. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[4],
  504. m_child2OfChild2->m_entity.get()
  505. );
  506. EXPECT_EQ(
  507. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[5],
  508. m_childOfChild2->m_entity.get()
  509. );
  510. }
  511. }
  512. TEST_F(ServerBranchedHierarchyTests, Detach_Child_While_Child2_Remains_Attached)
  513. {
  514. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  515. EXPECT_EQ(
  516. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  517. 4
  518. );
  519. if (m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 4)
  520. {
  521. EXPECT_EQ(
  522. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  523. m_root->m_entity.get()
  524. );
  525. EXPECT_EQ(
  526. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  527. m_child2->m_entity.get()
  528. );
  529. EXPECT_EQ(
  530. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  531. m_child2OfChild2->m_entity.get()
  532. );
  533. EXPECT_EQ(
  534. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[3],
  535. m_childOfChild2->m_entity.get()
  536. );
  537. }
  538. EXPECT_EQ(
  539. m_child2->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchicalRoot(),
  540. m_root->m_entity.get()
  541. );
  542. EXPECT_EQ(
  543. m_child->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchicalRoot(),
  544. nullptr
  545. );
  546. EXPECT_EQ(
  547. m_childOfChild->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchicalRoot(),
  548. nullptr
  549. );
  550. }
  551. TEST_F(ServerBranchedHierarchyTests, Detach_Child_Then_Attach_To_Child2)
  552. {
  553. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  554. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  555. EXPECT_EQ(
  556. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  557. 6
  558. );
  559. }
  560. /*
  561. * Sets up 2 deep hierarchies.
  562. */
  563. class ServerHierarchyOfHierarchyTests : public ServerDeepHierarchyTests
  564. {
  565. public:
  566. const NetEntityId Root2NetEntityId = NetEntityId{ 4 };
  567. const NetEntityId Child2NetEntityId = NetEntityId{ 5 };
  568. const NetEntityId ChildOfChild2NetEntityId = NetEntityId{ 6 };
  569. void SetUp() override
  570. {
  571. ServerDeepHierarchyTests::SetUp();
  572. m_root2 = AZStd::make_unique<EntityInfo>((4), "root 2", Root2NetEntityId, EntityInfo::Role::Root);
  573. m_child2 = AZStd::make_unique<EntityInfo>((5), "child 2", Child2NetEntityId, EntityInfo::Role::Child);
  574. m_childOfChild2 = AZStd::make_unique<EntityInfo>((6), "child of child 2", ChildOfChild2NetEntityId, EntityInfo::Role::Child);
  575. CreateDeepHierarchy(*m_root2, *m_child2, *m_childOfChild2);
  576. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root2->m_entity->GetId());
  577. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  578. // now the entities are under one hierarchy
  579. }
  580. void TearDown() override
  581. {
  582. m_childOfChild2.reset();
  583. m_child2.reset();
  584. m_root2.reset();
  585. ServerDeepHierarchyTests::TearDown();
  586. }
  587. AZStd::unique_ptr<EntityInfo> m_root2;
  588. AZStd::unique_ptr<EntityInfo> m_child2;
  589. AZStd::unique_ptr<EntityInfo> m_childOfChild2;
  590. };
  591. TEST_F(ServerHierarchyOfHierarchyTests, Hierarchies_Are_Not_Related)
  592. {
  593. EXPECT_EQ(
  594. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  595. 3
  596. );
  597. if (m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 3)
  598. {
  599. EXPECT_EQ(
  600. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  601. m_root->m_entity.get()
  602. );
  603. EXPECT_EQ(
  604. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  605. m_child->m_entity.get()
  606. );
  607. EXPECT_EQ(
  608. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  609. m_childOfChild->m_entity.get()
  610. );
  611. }
  612. EXPECT_EQ(
  613. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  614. 3
  615. );
  616. if (m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 3)
  617. {
  618. EXPECT_EQ(
  619. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  620. m_root2->m_entity.get()
  621. );
  622. EXPECT_EQ(
  623. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  624. m_child2->m_entity.get()
  625. );
  626. EXPECT_EQ(
  627. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  628. m_childOfChild2->m_entity.get()
  629. );
  630. }
  631. }
  632. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Is_Not_Top_Level_Root)
  633. {
  634. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  635. EXPECT_EQ(
  636. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  637. false
  638. );
  639. EXPECT_EQ(
  640. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  641. true
  642. );
  643. }
  644. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_References_All_When_Another_Hierarchy_Attached_At_Root)
  645. {
  646. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  647. EXPECT_EQ(
  648. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  649. 6
  650. );
  651. }
  652. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_References_All_When_Another_Hierarchy_Attached_At_Child)
  653. {
  654. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  655. EXPECT_EQ(
  656. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  657. 6
  658. );
  659. }
  660. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_References_All_When_Another_Hierarchy_Attached_At_Child_Of_Child)
  661. {
  662. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  663. EXPECT_EQ(
  664. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  665. 6
  666. );
  667. }
  668. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_References_Top_Root_When_Another_Hierarchy_Attached_At_Root)
  669. {
  670. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  671. EXPECT_EQ(
  672. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  673. true
  674. );
  675. EXPECT_EQ(
  676. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchyRoot(),
  677. RootNetEntityId
  678. );
  679. }
  680. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_References_Top_Root_When_Another_Hierarchy_Attached_At_Child)
  681. {
  682. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  683. EXPECT_EQ(
  684. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  685. true
  686. );
  687. EXPECT_EQ(
  688. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchyRoot(),
  689. RootNetEntityId
  690. );
  691. }
  692. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_References_Top_Root_When_Another_Hierarchy_Attached_At_Child_Of_Child)
  693. {
  694. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  695. EXPECT_EQ(
  696. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  697. true
  698. );
  699. EXPECT_EQ(
  700. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchyRoot(),
  701. RootNetEntityId
  702. );
  703. }
  704. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Doesnt_Keep_Child_References)
  705. {
  706. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  707. EXPECT_EQ(
  708. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  709. 0
  710. );
  711. }
  712. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_Child_References_After_Detachment_From_Top_Root)
  713. {
  714. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  715. // detach
  716. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  717. EXPECT_EQ(
  718. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  719. 3
  720. );
  721. if (m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size() == 3)
  722. {
  723. EXPECT_EQ(
  724. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[0],
  725. m_root2->m_entity.get()
  726. );
  727. EXPECT_EQ(
  728. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[1],
  729. m_child2->m_entity.get()
  730. );
  731. EXPECT_EQ(
  732. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities()[2],
  733. m_childOfChild2->m_entity.get()
  734. );
  735. }
  736. }
  737. TEST_F(ServerHierarchyOfHierarchyTests, InnerChildrenPointToInnerRootAfterDetachmentFromTopRoot)
  738. {
  739. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  740. // detach
  741. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  742. EXPECT_EQ(
  743. m_child2->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  744. m_root2->m_entity->FindComponent<NetBindComponent>()->GetNetEntityId()
  745. );
  746. EXPECT_EQ(
  747. m_childOfChild2->m_entity->FindComponent<NetworkHierarchyChildComponent>()->GetHierarchyRoot(),
  748. m_root2->m_entity->FindComponent<NetBindComponent>()->GetNetEntityId()
  749. );
  750. }
  751. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_Child_References_After_Detachment_From_Child_Of_Child)
  752. {
  753. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  754. // detach
  755. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  756. EXPECT_EQ(
  757. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  758. 3
  759. );
  760. }
  761. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_Child_References_After_Top_Root_Deactivates)
  762. {
  763. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  764. m_root.reset();
  765. EXPECT_EQ(
  766. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  767. 3
  768. );
  769. }
  770. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_Child_References_After_Child_Of_Top_Root_Deactivates)
  771. {
  772. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  773. m_child.reset();
  774. EXPECT_EQ(
  775. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  776. 3
  777. );
  778. }
  779. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_Child_References_After_Child_Of_Child_Deactivates)
  780. {
  781. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  782. m_childOfChild.reset();
  783. EXPECT_EQ(
  784. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  785. 3
  786. );
  787. }
  788. TEST_F(ServerHierarchyOfHierarchyTests, Stress_Test_Inner_Root_Has_Child_References_After_Detachment_From_Child_Of_Child)
  789. {
  790. for (int i = 0; i < 100; ++i)
  791. {
  792. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  793. // detach
  794. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  795. }
  796. EXPECT_EQ(
  797. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  798. 3
  799. );
  800. }
  801. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_Updates_Child_References_After_Detachment_Of_Child_Of_Child_In_Inner_Hierarchy)
  802. {
  803. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  804. // detach
  805. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  806. EXPECT_EQ(
  807. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  808. 5
  809. );
  810. }
  811. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_Updates_Child_References_After_Attachment_Of_Child_Of_Child_In_Inner_Hierarchy)
  812. {
  813. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  814. // detach
  815. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  816. // re-connect
  817. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  818. EXPECT_EQ(
  819. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  820. 6
  821. );
  822. }
  823. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_Updates_Child_References_After_Child_Of_Child_Changed_Hierarchies)
  824. {
  825. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  826. // detach
  827. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  828. // connect to a different hierarchy
  829. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  830. EXPECT_EQ(
  831. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  832. 6
  833. );
  834. }
  835. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_Updates_Child_References_After_Detachment_Of_Child_In_Inner_Hierarchy)
  836. {
  837. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  838. // detach
  839. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  840. EXPECT_EQ(
  841. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  842. 4
  843. );
  844. }
  845. TEST_F(ServerHierarchyOfHierarchyTests, Top_Root_Updates_Child_References_After_Child_Changed_Hierarchies)
  846. {
  847. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  848. // detach
  849. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  850. // connect to a different hierarchy
  851. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  852. EXPECT_EQ(
  853. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  854. 6
  855. );
  856. }
  857. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Has_No_Child_References_After_All_Children_Moved_To_Another_Hierarchy)
  858. {
  859. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  860. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  861. // detach
  862. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  863. EXPECT_EQ(
  864. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  865. 1
  866. );
  867. }
  868. TEST_F(ServerHierarchyOfHierarchyTests, Inner_Root_Child_Deactivated_Top_Root_Has_No_Child_Reference_To_It)
  869. {
  870. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  871. m_child2.reset();
  872. EXPECT_EQ(
  873. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  874. 4
  875. );
  876. }
  877. TEST_F(ServerHierarchyOfHierarchyTests, Testing_Limiting_Hierarchy_Maximum_Size)
  878. {
  879. uint32_t currentMaxLimit = 0;
  880. m_console->GetCvarValue<uint32_t>("bg_hierarchyEntityMaxLimit", currentMaxLimit);
  881. m_console->PerformCommand("bg_hierarchyEntityMaxLimit 2");
  882. // remake the top level hierarchy
  883. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  884. m_root->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  885. EXPECT_EQ(
  886. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  887. 2
  888. );
  889. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  890. EXPECT_EQ(
  891. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  892. 2
  893. );
  894. m_console->PerformCommand((AZStd::string("bg_hierarchyEntityMaxLimit ") + AZStd::to_string(currentMaxLimit)).c_str());
  895. m_console->GetCvarValue<uint32_t>("bg_hierarchyEntityMaxLimit", currentMaxLimit);
  896. }
  897. TEST_F(ServerHierarchyOfHierarchyTests, InnerRootAndItsChildrenHaveOwningConnectionIdOfTopRoot)
  898. {
  899. // Assign new connection ids.
  900. m_root->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 1 });
  901. m_root2->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 2 });
  902. // Attach then inner hierarchy's owning connection id should then be top root's connection id.
  903. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  904. EXPECT_EQ(
  905. m_root2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  906. m_root->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  907. );
  908. EXPECT_EQ(
  909. m_child2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  910. m_root->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  911. );
  912. EXPECT_EQ(
  913. m_childOfChild2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  914. m_root->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  915. );
  916. }
  917. TEST_F(ServerHierarchyOfHierarchyTests, InnerRootAndItsChildrenHaveTheirOriginalOwningConnectionIdAfterDetachingFromTopRoot)
  918. {
  919. // Assign new connection ids.
  920. m_root->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 1 });
  921. m_root2->m_entity->FindComponent<NetBindComponent>()->SetOwningConnectionId(ConnectionId{ 2 });
  922. // Attach then inner hierarchy's owning connection id should then be top root's connection id.
  923. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  924. // detach, inner hierarchy should roll back to his previous owning connection id
  925. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  926. EXPECT_EQ(
  927. m_root2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  928. ConnectionId{ 2 }
  929. );
  930. EXPECT_EQ(
  931. m_child2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  932. m_root2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  933. );
  934. EXPECT_EQ(
  935. m_childOfChild2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId(),
  936. m_root2->m_entity->FindComponent<NetBindComponent>()->GetOwningConnectionId()
  937. );
  938. }
  939. /*
  940. * Parent -> Child -> ChildOfChild (not marked as in a hierarchy)
  941. */
  942. class ServerMixedDeepHierarchyTests : public HierarchyTests
  943. {
  944. public:
  945. void SetUp() override
  946. {
  947. HierarchyTests::SetUp();
  948. m_root = AZStd::make_unique<EntityInfo>((1), "root", NetEntityId{ 1 }, EntityInfo::Role::Root);
  949. m_child = AZStd::make_unique<EntityInfo>((2), "child", NetEntityId{ 2 }, EntityInfo::Role::Child);
  950. m_childOfChild = AZStd::make_unique<EntityInfo>((3), "child of child", NetEntityId{ 3 }, EntityInfo::Role::None);
  951. CreateDeepHierarchy(*m_root, *m_child, *m_childOfChild);
  952. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  953. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child->m_entity->GetId());
  954. // now the entities are under one hierarchy
  955. }
  956. void TearDown() override
  957. {
  958. m_childOfChild.reset();
  959. m_child.reset();
  960. m_root.reset();
  961. HierarchyTests::TearDown();
  962. }
  963. AZStd::unique_ptr<EntityInfo> m_root;
  964. AZStd::unique_ptr<EntityInfo> m_child;
  965. AZStd::unique_ptr<EntityInfo> m_childOfChild;
  966. };
  967. TEST_F(ServerMixedDeepHierarchyTests, Top_Root_Ignores_Non_Hierarchical_Entities)
  968. {
  969. EXPECT_EQ(
  970. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  971. 2
  972. );
  973. }
  974. TEST_F(ServerMixedDeepHierarchyTests, Detaching_Non_Hierarchical_Entity_Has_No_Effect_On_Top_Root)
  975. {
  976. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  977. EXPECT_EQ(
  978. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  979. 2
  980. );
  981. }
  982. TEST_F(ServerMixedDeepHierarchyTests, Attaching_Non_Hierarchical_Entity_Has_No_Effect_On_Top_Root)
  983. {
  984. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  985. m_childOfChild->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  986. EXPECT_EQ(
  987. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  988. 2
  989. );
  990. }
  991. /*
  992. * 1st hierarchy: Parent -> Child -> ChildOfChild (not marked as in a hierarchy)
  993. * 2nd hierarchy: Parent2 -> Child2 (not marked as in a hierarchy) -> ChildOfChild2
  994. */
  995. class ServerMixedHierarchyOfHierarchyTests : public ServerMixedDeepHierarchyTests
  996. {
  997. public:
  998. void SetUp() override
  999. {
  1000. ServerMixedDeepHierarchyTests::SetUp();
  1001. m_root2 = AZStd::make_unique<EntityInfo>((4), "root 2", NetEntityId{ 4 }, EntityInfo::Role::Root);
  1002. m_child2 = AZStd::make_unique<EntityInfo>((5), "child 2", NetEntityId{ 5 }, EntityInfo::Role::None);
  1003. m_childOfChild2 = AZStd::make_unique<EntityInfo>((6), "child of child 2", NetEntityId{ 6 }, EntityInfo::Role::Child);
  1004. CreateDeepHierarchy(*m_root2, *m_child2, *m_childOfChild2);
  1005. m_child2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root2->m_entity->GetId());
  1006. m_childOfChild2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child2->m_entity->GetId());
  1007. // now the entities are under one hierarchy
  1008. }
  1009. void TearDown() override
  1010. {
  1011. m_childOfChild2.reset();
  1012. m_child2.reset();
  1013. m_root2.reset();
  1014. ServerMixedDeepHierarchyTests::TearDown();
  1015. }
  1016. AZStd::unique_ptr<EntityInfo> m_root2;
  1017. AZStd::unique_ptr<EntityInfo> m_child2;
  1018. AZStd::unique_ptr<EntityInfo> m_childOfChild2;
  1019. };
  1020. TEST_F(ServerMixedHierarchyOfHierarchyTests, Sanity_Check_Ingore_Children_Without_Hierarchy_Components)
  1021. {
  1022. EXPECT_EQ(
  1023. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1024. 2
  1025. );
  1026. EXPECT_EQ(
  1027. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1028. 1
  1029. );
  1030. }
  1031. TEST_F(ServerMixedHierarchyOfHierarchyTests, Adding_Mixed_Hierarchy_Ingores_Children_Without_Hierarchy_Components)
  1032. {
  1033. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root->m_entity->GetId());
  1034. EXPECT_EQ(
  1035. m_root->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1036. 3
  1037. );
  1038. }
  1039. TEST_F(ServerMixedHierarchyOfHierarchyTests, Attaching_Hierarchy_To_Non_Hierarchical_Entity_Does_Not_Merge_Hierarchies)
  1040. {
  1041. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1042. EXPECT_EQ(
  1043. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->IsHierarchicalChild(),
  1044. false
  1045. );
  1046. }
  1047. /*
  1048. * Sets up a hierarchy with 3 roots, 2 of them being inner roots.
  1049. */
  1050. class ServerHierarchyWithThreeRoots : public ServerHierarchyOfHierarchyTests
  1051. {
  1052. public:
  1053. const NetEntityId Root3NetEntityId = NetEntityId{ 7 };
  1054. const NetEntityId Child3NetEntityId = NetEntityId{ 8 };
  1055. const NetEntityId ChildOfChild3NetEntityId = NetEntityId{ 9 };
  1056. void SetUp() override
  1057. {
  1058. ServerHierarchyOfHierarchyTests::SetUp();
  1059. m_root3 = AZStd::make_unique<EntityInfo>((7), "root 3", Root3NetEntityId, EntityInfo::Role::Root);
  1060. m_child3 = AZStd::make_unique<EntityInfo>((8), "child 3", Child3NetEntityId, EntityInfo::Role::Child);
  1061. m_childOfChild3 = AZStd::make_unique<EntityInfo>((9), "child of child 3", ChildOfChild3NetEntityId, EntityInfo::Role::Child);
  1062. CreateDeepHierarchy(*m_root3, *m_child3, *m_childOfChild3);
  1063. m_child3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_root3->m_entity->GetId());
  1064. m_childOfChild3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_child3->m_entity->GetId());
  1065. // now the entities are under one hierarchy
  1066. }
  1067. void TearDown() override
  1068. {
  1069. m_childOfChild3.reset();
  1070. m_child3.reset();
  1071. m_root3.reset();
  1072. ServerHierarchyOfHierarchyTests::TearDown();
  1073. }
  1074. AZStd::unique_ptr<EntityInfo> m_root3;
  1075. AZStd::unique_ptr<EntityInfo> m_child3;
  1076. AZStd::unique_ptr<EntityInfo> m_childOfChild3;
  1077. };
  1078. TEST_F(ServerHierarchyWithThreeRoots, Top_Root_Active_Then_Inner_Roots_Have_No_Child_References)
  1079. {
  1080. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1081. m_root3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1082. EXPECT_EQ(
  1083. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1084. 0
  1085. );
  1086. EXPECT_EQ(
  1087. m_root3->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1088. 0
  1089. );
  1090. }
  1091. TEST_F(ServerHierarchyWithThreeRoots, Top_Root_Deactivates_Inner_Roots_Have_Child_References)
  1092. {
  1093. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1094. m_root3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1095. m_root.reset();
  1096. EXPECT_EQ(
  1097. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1098. 3
  1099. );
  1100. EXPECT_EQ(
  1101. m_root3->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1102. 3
  1103. );
  1104. }
  1105. TEST_F(ServerHierarchyWithThreeRoots, Child_Of_Top_Root_Deactivates_Inner_Roots_Have_Child_References)
  1106. {
  1107. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1108. m_root3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1109. m_child.reset();
  1110. EXPECT_EQ(
  1111. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1112. 3
  1113. );
  1114. EXPECT_EQ(
  1115. m_root3->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1116. 3
  1117. );
  1118. }
  1119. TEST_F(ServerHierarchyWithThreeRoots, Child_Of_Child_Of_Top_Root_Deactivates_Inner_Roots_Have_Child_References)
  1120. {
  1121. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1122. m_root3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1123. m_childOfChild.reset();
  1124. EXPECT_EQ(
  1125. m_root2->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1126. 3
  1127. );
  1128. EXPECT_EQ(
  1129. m_root3->m_entity->FindComponent<NetworkHierarchyRootComponent>()->GetHierarchicalEntities().size(),
  1130. 3
  1131. );
  1132. }
  1133. TEST_F(ServerHierarchyWithThreeRoots, InnerRootLeftTopRootThenLastChildGetsJoinedEventOnce)
  1134. {
  1135. m_root2->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1136. m_root3->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(m_childOfChild->m_entity->GetId());
  1137. MockNetworkHierarchyCallbackHandler mock;
  1138. EXPECT_CALL(mock, OnNetworkHierarchyUpdated(m_root3->m_entity->GetId()));
  1139. m_childOfChild3->m_entity->FindComponent<NetworkHierarchyChildComponent>()->BindNetworkHierarchyChangedEventHandler(mock.m_changedHandler);
  1140. m_child->m_entity->FindComponent<AzFramework::TransformComponent>()->SetParent(AZ::EntityId());
  1141. }
  1142. }