CommonNetworkEntitySetup.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  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. #pragma once
  8. #include <IMultiplayerConnectionMock.h>
  9. #include <MockInterfaces.h>
  10. #include <AzCore/Component/Entity.h>
  11. #include <AzCore/EBus/EventSchedulerSystemComponent.h>
  12. #include <AzCore/Console/Console.h>
  13. #include <AzCore/Math/Vector3.h>
  14. #include <AzCore/Name/Name.h>
  15. #include <AzCore/Name/NameDictionary.h>
  16. #include <AzCore/RTTI/BehaviorContext.h>
  17. #include <AzCore/Serialization/SerializeContext.h>
  18. #include <AzCore/UnitTest/TestTypes.h>
  19. #include <AzCore/UnitTest/UnitTest.h>
  20. #include <AzCore/UnitTest/Mocks/MockITime.h>
  21. #include <AzFramework/Components/TransformComponent.h>
  22. #include <AzFramework/Visibility/EntityVisibilityBoundsUnionSystem.h>
  23. #include <AzNetworking/Serialization/NetworkInputSerializer.h>
  24. #include <AzNetworking/Serialization/NetworkOutputSerializer.h>
  25. #include <AzTest/AzTest.h>
  26. #include <Multiplayer/IMultiplayer.h>
  27. #include <Multiplayer/Components/NetBindComponent.h>
  28. #include <Multiplayer/Components/NetworkHierarchyChildComponent.h>
  29. #include <Multiplayer/Components/NetworkHierarchyRootComponent.h>
  30. #include <Multiplayer/Components/NetworkTransformComponent.h>
  31. #include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicationManager.h>
  32. #include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
  33. #include <Source/NetworkEntity/NetworkEntityManager.h>
  34. #include <NetworkEntity/NetworkEntityAuthorityTracker.h>
  35. #include <NetworkEntity/NetworkEntityTracker.h>
  36. #include <Tests/TestMultiplayerComponent.h>
  37. namespace Multiplayer
  38. {
  39. using namespace testing;
  40. using namespace ::UnitTest;
  41. class NetworkEntityTests
  42. : public LeakDetectionFixture
  43. {
  44. public:
  45. void SetUp() override
  46. {
  47. AZ::NameDictionary::Create();
  48. m_mockComponentApplicationRequests = AZStd::make_unique<NiceMock<MockComponentApplicationRequests>>();
  49. AZ::Interface<AZ::ComponentApplicationRequests>::Register(m_mockComponentApplicationRequests.get());
  50. ON_CALL(*m_mockComponentApplicationRequests, AddEntity(_)).WillByDefault(Invoke(this, &NetworkEntityTests::AddEntity));
  51. ON_CALL(*m_mockComponentApplicationRequests, FindEntity(_)).WillByDefault(Invoke(this, &NetworkEntityTests::FindEntity));
  52. // register components involved in testing
  53. m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
  54. m_behaviorContext = AZStd::make_unique<AZ::BehaviorContext>();
  55. m_transformDescriptor.reset(AzFramework::TransformComponent::CreateDescriptor());
  56. m_transformDescriptor->Reflect(m_serializeContext.get());
  57. m_netBindDescriptor.reset(NetBindComponent::CreateDescriptor());
  58. m_netBindDescriptor->Reflect(m_serializeContext.get());
  59. m_netBindDescriptor->Reflect(m_behaviorContext.get());
  60. m_netTransformDescriptor.reset(NetworkTransformComponent::CreateDescriptor());
  61. m_netTransformDescriptor->Reflect(m_serializeContext.get());
  62. m_testMultiplayerComponentDescriptor.reset(MultiplayerTest::TestMultiplayerComponent::CreateDescriptor());
  63. m_testMultiplayerComponentDescriptor->Reflect(m_serializeContext.get());
  64. m_testInputDriverComponentDescriptor.reset(MultiplayerTest::TestInputDriverComponent::CreateDescriptor());
  65. m_testInputDriverComponentDescriptor->Reflect(m_serializeContext.get());
  66. m_mockMultiplayer = AZStd::make_unique<NiceMock<MockMultiplayer>>();
  67. AZ::Interface<IMultiplayer>::Register(m_mockMultiplayer.get());
  68. EXPECT_NE(AZ::Interface<IMultiplayer>::Get(), nullptr);
  69. // Create space for replication stats
  70. // Without Multiplayer::RegisterMultiplayerComponents() the stats go to invalid id, which is fine for unit tests
  71. GetMultiplayer()->GetStats().ReserveComponentStats(Multiplayer::InvalidNetComponentId, 50, 0);
  72. m_visisbilitySystem = AZStd::make_unique<AzFramework::EntityVisibilityBoundsUnionSystem>();
  73. m_visisbilitySystem->Connect();
  74. m_networkEntityManager = AZStd::make_unique<NetworkEntityManager>();
  75. m_mockTime = AZStd::make_unique<AZ::NiceTimeSystemMock>();
  76. m_eventScheduler = AZStd::make_unique<AZ::EventSchedulerSystemComponent>();
  77. m_mockNetworkTime = AZStd::make_unique<NiceMock<MockNetworkTime>>();
  78. AZ::Interface<INetworkTime>::Register(m_mockNetworkTime.get());
  79. ON_CALL(*m_mockMultiplayer, GetNetworkEntityManager()).WillByDefault(Return(m_networkEntityManager.get()));
  80. EXPECT_NE(AZ::Interface<IMultiplayer>::Get()->GetNetworkEntityManager(), nullptr);
  81. const IpAddress address("localhost", 1, ProtocolType::Udp);
  82. m_mockConnection = AZStd::make_unique<NiceMock<IMultiplayerConnectionMock>>(ConnectionId{ 1 }, address, ConnectionRole::Connector);
  83. m_mockConnectionListener = AZStd::make_unique<MockConnectionListener>();
  84. m_entityReplicationManager = AZStd::make_unique<EntityReplicationManager>(*m_mockConnection, *m_mockConnectionListener, EntityReplicationManager::Mode::LocalClientToRemoteServer);
  85. m_console.reset(aznew AZ::Console());
  86. AZ::Interface<AZ::IConsole>::Register(m_console.get());
  87. m_console->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
  88. m_multiplayerComponentRegistry = AZStd::make_unique<MultiplayerComponentRegistry>();
  89. RegisterMultiplayerComponents();
  90. MultiplayerTest::RegisterMultiplayerComponents();
  91. }
  92. void TearDown() override
  93. {
  94. m_multiplayerComponentRegistry.reset();
  95. AZ::Interface<AZ::IConsole>::Unregister(m_console.get());
  96. m_console.reset();
  97. m_entities.clear();
  98. m_entityReplicationManager.reset();
  99. m_mockConnection.reset();
  100. m_mockConnectionListener.reset();
  101. AZ::Interface<INetworkTime>::Unregister(m_mockNetworkTime.get());
  102. AZ::Interface<IMultiplayer>::Unregister(m_mockMultiplayer.get());
  103. AZ::Interface<AZ::ComponentApplicationRequests>::Unregister(m_mockComponentApplicationRequests.get());
  104. m_eventScheduler.reset();
  105. m_mockTime.reset();
  106. m_networkEntityManager.reset();
  107. m_mockMultiplayer.reset();
  108. m_visisbilitySystem->Disconnect();
  109. m_visisbilitySystem.reset();
  110. m_testInputDriverComponentDescriptor.reset();
  111. m_testMultiplayerComponentDescriptor.reset();
  112. m_transformDescriptor.reset();
  113. m_netTransformDescriptor.reset();
  114. m_hierarchyRootDescriptor.reset();
  115. m_hierarchyChildDescriptor.reset();
  116. m_netBindDescriptor.reset();
  117. m_behaviorContext.reset();
  118. m_serializeContext.reset();
  119. m_mockComponentApplicationRequests.reset();
  120. AZ::NameDictionary::Destroy();
  121. }
  122. AZStd::unique_ptr<AZ::IConsole> m_console;
  123. AZStd::unique_ptr<NiceMock<MockComponentApplicationRequests>> m_mockComponentApplicationRequests;
  124. AZStd::unique_ptr<AZ::SerializeContext> m_serializeContext;
  125. AZStd::unique_ptr<AZ::BehaviorContext> m_behaviorContext;
  126. AZStd::unique_ptr<AZ::ComponentDescriptor> m_transformDescriptor;
  127. AZStd::unique_ptr<AZ::ComponentDescriptor> m_netBindDescriptor;
  128. AZStd::unique_ptr<AZ::ComponentDescriptor> m_hierarchyRootDescriptor;
  129. AZStd::unique_ptr<AZ::ComponentDescriptor> m_hierarchyChildDescriptor;
  130. AZStd::unique_ptr<AZ::ComponentDescriptor> m_netTransformDescriptor;
  131. AZStd::unique_ptr<AZ::ComponentDescriptor> m_testMultiplayerComponentDescriptor;
  132. AZStd::unique_ptr<AZ::ComponentDescriptor> m_testInputDriverComponentDescriptor;
  133. AZStd::unique_ptr<NiceMock<MockMultiplayer>> m_mockMultiplayer;
  134. AZStd::unique_ptr<NetworkEntityManager> m_networkEntityManager;
  135. AZStd::unique_ptr<AZ::EventSchedulerSystemComponent> m_eventScheduler;
  136. AZStd::unique_ptr<AZ::NiceTimeSystemMock> m_mockTime;
  137. AZStd::unique_ptr<NiceMock<MockNetworkTime>> m_mockNetworkTime;
  138. AZStd::unique_ptr<AzFramework::EntityVisibilityBoundsUnionSystem> m_visisbilitySystem;
  139. AZStd::unique_ptr<NiceMock<IMultiplayerConnectionMock>> m_mockConnection;
  140. AZStd::unique_ptr<MockConnectionListener> m_mockConnectionListener;
  141. AZStd::unique_ptr<EntityReplicationManager> m_entityReplicationManager;
  142. AZStd::unique_ptr<MultiplayerComponentRegistry> m_multiplayerComponentRegistry;;
  143. AZStd::map<AZ::EntityId, AZ::Entity*> m_entities;
  144. bool AddEntity(AZ::Entity* entity)
  145. {
  146. m_entities[entity->GetId()] = entity;
  147. return true;
  148. }
  149. AZ::Entity* FindEntity(AZ::EntityId entityId)
  150. {
  151. const auto iterator = m_entities.find(entityId);
  152. if (iterator != m_entities.end())
  153. {
  154. return iterator->second;
  155. }
  156. return nullptr;
  157. }
  158. void SetupEntity(const AZStd::unique_ptr<AZ::Entity>& entity, NetEntityId netId, NetEntityRole role)
  159. {
  160. if (const auto netBindComponent = entity->FindComponent<Multiplayer::NetBindComponent>())
  161. {
  162. netBindComponent->PreInit(entity.get(), PrefabEntityId{ AZ::Name("test"), 1 }, netId, role);
  163. entity->Init();
  164. }
  165. }
  166. static void StopEntity(const AZStd::unique_ptr<AZ::Entity>& entity)
  167. {
  168. if (const auto netBindComponent = entity->FindComponent<Multiplayer::NetBindComponent>())
  169. {
  170. netBindComponent->StopEntity();
  171. }
  172. }
  173. static void StopAndDeactivateEntity(AZStd::unique_ptr<AZ::Entity>& entity)
  174. {
  175. if (entity)
  176. {
  177. StopEntity(entity);
  178. entity->Deactivate();
  179. entity.reset();
  180. }
  181. }
  182. struct EntityInfo
  183. {
  184. enum class Role
  185. {
  186. Root,
  187. Child,
  188. None
  189. };
  190. EntityInfo(AZ::u64 entityId, const char* entityName, NetEntityId netId, Role role)
  191. : m_entity(AZStd::make_unique<AZ::Entity>(AZ::EntityId(entityId), entityName))
  192. , m_netId(netId)
  193. , m_role(role)
  194. {
  195. }
  196. ~EntityInfo()
  197. {
  198. StopAndDeactivateEntity(m_entity);
  199. }
  200. AZStd::unique_ptr<AZ::Entity> m_entity;
  201. NetEntityId m_netId;
  202. AZStd::unique_ptr<EntityReplicator> m_replicator;
  203. Role m_role = Role::None;
  204. };
  205. void PopulateHierarchicalEntity(const EntityInfo& entityInfo)
  206. {
  207. entityInfo.m_entity->CreateComponent<AzFramework::TransformComponent>();
  208. entityInfo.m_entity->CreateComponent<NetBindComponent>();
  209. entityInfo.m_entity->CreateComponent<NetworkTransformComponent>();
  210. entityInfo.m_entity->CreateComponent<MultiplayerTest::TestMultiplayerComponent>();
  211. entityInfo.m_entity->CreateComponent<MultiplayerTest::TestInputDriverComponent>();
  212. switch (entityInfo.m_role)
  213. {
  214. case EntityInfo::Role::Root:
  215. entityInfo.m_entity->CreateComponent<NetworkHierarchyRootComponent>();
  216. break;
  217. case EntityInfo::Role::Child:
  218. entityInfo.m_entity->CreateComponent<NetworkHierarchyChildComponent>();
  219. break;
  220. case EntityInfo::Role::None:
  221. break;
  222. }
  223. }
  224. };
  225. }