merging latest dev + resolving 1 conflict
Signed-off-by: Gene Walters <genewalt@amazon.com>
This commit is contained in:
@@ -403,6 +403,8 @@ namespace {{ Component.attrib['Namespace'] }}
|
||||
: public Multiplayer::MultiplayerController
|
||||
{
|
||||
public:
|
||||
using ComponentType = {{ ComponentName }};
|
||||
|
||||
{{ ControllerBaseName }}({{ ComponentName }}& owner);
|
||||
~{{ ControllerBaseName }}() override = default;
|
||||
|
||||
|
||||
+2
-2
@@ -83,8 +83,8 @@ namespace Multiplayer
|
||||
AZ::ScheduledEvent m_autonomousUpdateEvent; // Drives autonomous input collection
|
||||
AZ::ScheduledEvent m_updateBankedTimeEvent; // Drives authority bank time updates
|
||||
|
||||
EntityMigrationStartEvent::Handler m_migrateStartHandler;
|
||||
EntityMigrationEndEvent::Handler m_migrateEndHandler;
|
||||
ClientMigrationStartEvent::Handler m_migrateStartHandler;
|
||||
ClientMigrationEndEvent::Handler m_migrateEndHandler;
|
||||
|
||||
double m_moveAccumulator = 0.0;
|
||||
double m_clientBankedTime = 0.0;
|
||||
|
||||
@@ -67,6 +67,9 @@ namespace Multiplayer
|
||||
//! @return reference to the requested component data, an empty container will be returned if the NetComponentId does not exist
|
||||
const ComponentData& GetMultiplayerComponentData(NetComponentId netComponentId) const;
|
||||
|
||||
//! This releases all owned memory, should only be called during multiplayer shutdown.
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
NetComponentId m_nextNetComponentId = NetComponentId{ 0 };
|
||||
AZStd::unordered_map<NetComponentId, ComponentData> m_componentData;
|
||||
|
||||
@@ -32,9 +32,7 @@ namespace Multiplayer
|
||||
using EntityStopEvent = AZ::Event<const ConstNetworkEntityHandle&>;
|
||||
using EntityDirtiedEvent = AZ::Event<>;
|
||||
using EntitySyncRewindEvent = AZ::Event<>;
|
||||
using EntityMigrationStartEvent = AZ::Event<ClientInputId>;
|
||||
using EntityMigrationEndEvent = AZ::Event<>;
|
||||
using EntityServerMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, HostId, AzNetworking::ConnectionId>;
|
||||
using EntityServerMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, const HostId&, AzNetworking::ConnectionId>;
|
||||
using EntityPreRenderEvent = AZ::Event<float>;
|
||||
using EntityCorrectionEvent = AZ::Event<>;
|
||||
|
||||
@@ -115,17 +113,13 @@ namespace Multiplayer
|
||||
void MarkDirty();
|
||||
void NotifyLocalChanges();
|
||||
void NotifySyncRewindState();
|
||||
void NotifyMigrationStart(ClientInputId migratedInputId);
|
||||
void NotifyMigrationEnd();
|
||||
void NotifyServerMigration(HostId hostId, AzNetworking::ConnectionId connectionId);
|
||||
void NotifyServerMigration(const HostId& hostId, AzNetworking::ConnectionId connectionId);
|
||||
void NotifyPreRender(float deltaTime);
|
||||
void NotifyCorrection();
|
||||
|
||||
void AddEntityStopEventHandler(EntityStopEvent::Handler& eventHandler);
|
||||
void AddEntityDirtiedEventHandler(EntityDirtiedEvent::Handler& eventHandler);
|
||||
void AddEntitySyncRewindEventHandler(EntitySyncRewindEvent::Handler& eventHandler);
|
||||
void AddEntityMigrationStartEventHandler(EntityMigrationStartEvent::Handler& eventHandler);
|
||||
void AddEntityMigrationEndEventHandler(EntityMigrationEndEvent::Handler& eventHandler);
|
||||
void AddEntityServerMigrationEventHandler(EntityServerMigrationEvent::Handler& eventHandler);
|
||||
void AddEntityPreRenderEventHandler(EntityPreRenderEvent::Handler& eventHandler);
|
||||
void AddEntityCorrectionEventHandler(EntityCorrectionEvent::Handler& handler);
|
||||
@@ -174,8 +168,6 @@ namespace Multiplayer
|
||||
EntityStopEvent m_entityStopEvent;
|
||||
EntityDirtiedEvent m_dirtiedEvent;
|
||||
EntitySyncRewindEvent m_syncRewindEvent;
|
||||
EntityMigrationStartEvent m_entityMigrationStartEvent;
|
||||
EntityMigrationEndEvent m_entityMigrationEndEvent;
|
||||
EntityServerMigrationEvent m_entityServerMigrationEvent;
|
||||
EntityPreRenderEvent m_entityPreRenderEvent;
|
||||
EntityCorrectionEvent m_entityCorrectionEvent;
|
||||
@@ -201,6 +193,7 @@ namespace Multiplayer
|
||||
friend class EntityReplicationManager;
|
||||
|
||||
friend class HierarchyTests;
|
||||
friend class HierarchyBenchmarkBase;
|
||||
};
|
||||
|
||||
bool NetworkRoleHasController(NetEntityRole networkRole);
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace Multiplayer
|
||||
};
|
||||
|
||||
typedef AZ::EBus<NetworkCharacterRequests> NetworkCharacterRequestBus;
|
||||
|
||||
|
||||
//! NetworkCharacterComponent
|
||||
//! Provides multiplayer support for game-play player characters.
|
||||
@@ -47,20 +46,11 @@ namespace Multiplayer
|
||||
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkCharacterComponent, s_networkCharacterComponentConcreteUuid, Multiplayer::NetworkCharacterComponentBase)
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
|
||||
|
||||
NetworkCharacterComponent();
|
||||
|
||||
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
|
||||
{
|
||||
incompatible.push_back(AZ_CRC_CE("NetworkRigidBodyService"));
|
||||
}
|
||||
|
||||
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
|
||||
{
|
||||
NetworkCharacterComponentBase::GetRequiredServices(required);
|
||||
required.push_back(AZ_CRC_CE("PhysXCharacterControllerService"));
|
||||
}
|
||||
|
||||
// AZ::Component
|
||||
void OnInit() override {}
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
@@ -96,5 +96,7 @@ namespace Multiplayer
|
||||
|
||||
//! Set to false when deactivating or otherwise not to be included in hierarchy considerations.
|
||||
bool m_isHierarchyEnabled = true;
|
||||
|
||||
friend class HierarchyBenchmarkBase;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Source/AutoGen/NetworkRigidBodyComponent.AutoComponent.h>
|
||||
@@ -60,10 +61,11 @@ namespace Multiplayer
|
||||
{
|
||||
public:
|
||||
NetworkRigidBodyComponentController(NetworkRigidBodyComponent& parent);
|
||||
|
||||
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
void HandleSendApplyImpulse(AzNetworking::IConnection* invokingConnection, const AZ::Vector3& impulse, const AZ::Vector3& worldPoint) override;
|
||||
private:
|
||||
void OnTransformUpdate();
|
||||
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
|
||||
};
|
||||
} // namespace Multiplayer
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace Multiplayer
|
||||
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
|
||||
|
||||
private:
|
||||
void OnTransformChangedEvent(const AZ::Transform& worldTm);
|
||||
void OnTransformChangedEvent(const AZ::Transform& localTm, const AZ::Transform& worldTm);
|
||||
void OnParentIdChangedEvent(AZ::EntityId oldParent, AZ::EntityId newParent);
|
||||
|
||||
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
|
||||
|
||||
@@ -40,8 +40,7 @@ namespace Multiplayer
|
||||
virtual EntityReplicationManager& GetReplicationManager() = 0;
|
||||
|
||||
//! Creates and manages sending updates to the remote endpoint.
|
||||
//! @param hostTimeMs current server game time in milliseconds
|
||||
virtual void Update(AZ::TimeMs hostTimeMs) = 0;
|
||||
virtual void Update() = 0;
|
||||
|
||||
//! Returns whether update messages can be sent to the connection.
|
||||
//! @return true if update messages can be sent
|
||||
@@ -50,5 +49,13 @@ namespace Multiplayer
|
||||
//! Sets the state of connection whether update messages can be sent or not.
|
||||
//! @param canSendUpdates the state value
|
||||
virtual void SetCanSendUpdates(bool canSendUpdates) = 0;
|
||||
|
||||
//! Fetches the state of connection whether handshake logic has completed
|
||||
//! @return true if handshake has completed
|
||||
virtual bool DidHandshake() const = 0;
|
||||
|
||||
//! Sets the state of connection whether handshake logic has completed
|
||||
//! @param didHandshake if handshake logic has completed
|
||||
virtual void SetDidHandshake(bool didHandshake) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -21,6 +21,14 @@ namespace Multiplayer
|
||||
|
||||
virtual ~IEntityDomain() = default;
|
||||
|
||||
//! For domains that operate on a region of space, this sets the area the domain is responsible for.
|
||||
//! @param aabb the aabb associated with this entity domain
|
||||
virtual void SetAabb(const AZ::Aabb& aabb) = 0;
|
||||
|
||||
//! Retrieves the aabb representing the domain area, an invalid aabb will be returned for non-spatial domains.
|
||||
//! @return the aabb associated with this entity domain
|
||||
virtual const AZ::Aabb& GetAabb() const = 0;
|
||||
|
||||
//! Returns whether or not an entity should be owned by an entity manager.
|
||||
//! @param entityHandle the handle of the netbound entity to check
|
||||
//! @return false if this entity should not belong to the entity manger, true if it could be owned by the entity manager
|
||||
@@ -31,8 +39,7 @@ namespace Multiplayer
|
||||
virtual void ActivateTracking(const INetworkEntityManager::OwnedEntitySet& ownedEntitySet) = 0;
|
||||
|
||||
//! Return the set of netbound entities not included in this domain.
|
||||
//! @param outEntitiesNotInDomain the set of known networked entities not included in this domain
|
||||
virtual void RetrieveEntitiesNotInDomain(EntitiesNotInDomain& outEntitiesNotInDomain) const = 0;
|
||||
virtual const EntitiesNotInDomain& RetrieveEntitiesNotInDomain() const = 0;
|
||||
|
||||
//! Debug draw to visualize host entity domains.
|
||||
virtual void DebugDraw() const = 0;
|
||||
|
||||
@@ -42,7 +42,11 @@ namespace Multiplayer
|
||||
AzNetworking::ByteBuffer<2048> m_userData;
|
||||
};
|
||||
|
||||
using ClientMigrationStartEvent = AZ::Event<ClientInputId>;
|
||||
using ClientMigrationEndEvent = AZ::Event<>;
|
||||
using ClientDisconnectedEvent = AZ::Event<>;
|
||||
using NotifyClientMigrationEvent = AZ::Event<const HostId&, uint64_t, ClientInputId>;
|
||||
using NotifyEntityMigrationEvent = AZ::Event<const ConstNetworkEntityHandle&, const HostId&>;
|
||||
using ConnectionAcquiredEvent = AZ::Event<MultiplayerAgentDatum>;
|
||||
using ServerAcceptanceReceivedEvent = AZ::Event<>;
|
||||
using SessionInitEvent = AZ::Event<AzNetworking::INetworkInterface*>;
|
||||
@@ -79,26 +83,42 @@ namespace Multiplayer
|
||||
//! @param state The state of this connection
|
||||
virtual void InitializeMultiplayer(MultiplayerAgentType state) = 0;
|
||||
|
||||
//! Starts hosting a server
|
||||
//! Starts hosting a server.
|
||||
//! @param port The port to listen for connection on
|
||||
//! @param isDedicated Whether the server is dedicated or client hosted
|
||||
//! @return if the application successfully started hosting
|
||||
virtual bool StartHosting(uint16_t port, bool isDedicated = true) = 0;
|
||||
|
||||
//! Connects to the specified IP as a Client
|
||||
//! Connects to the specified IP as a Client.
|
||||
//! @param remoteAddress The domain or IP to connect to
|
||||
//! @param port The port to connect to
|
||||
//! @result if a connection was successfully created
|
||||
virtual bool Connect(AZStd::string remoteAddress, uint16_t port) = 0;
|
||||
virtual bool Connect(const AZStd::string& remoteAddress, uint16_t port) = 0;
|
||||
|
||||
// Disconnects all multiplayer connections, stops listening on the server and invokes handlers appropriate to network context
|
||||
// Disconnects all multiplayer connections, stops listening on the server and invokes handlers appropriate to network context.
|
||||
//! @param reason The reason for terminating connections
|
||||
virtual void Terminate(AzNetworking::DisconnectReason reason) = 0;
|
||||
|
||||
//! Adds a ClientDisconnectedEvent Handler which is invoked on the client when a disconnection occurs
|
||||
//! Adds a ClientMigrationStartEvent Handler which is invoked at the start of a client migration.
|
||||
//! @param handler The ClientMigrationStartEvent Handler to add
|
||||
virtual void AddClientMigrationStartEventHandler(ClientMigrationStartEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a ClientMigrationEndEvent Handler which is invoked when a client completes migration.
|
||||
//! @param handler The ClientMigrationEndEvent Handler to add
|
||||
virtual void AddClientMigrationEndEventHandler(ClientMigrationEndEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a ClientDisconnectedEvent Handler which is invoked on the client when a disconnection occurs.
|
||||
//! @param handler The ClientDisconnectedEvent Handler to add
|
||||
virtual void AddClientDisconnectedHandler(ClientDisconnectedEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a NotifyClientMigrationEvent Handler which is invoked when a client migrates from one host to another.
|
||||
//! @param handler The NotifyClientMigrationEvent Handler to add
|
||||
virtual void AddNotifyClientMigrationHandler(NotifyClientMigrationEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a NotifyEntityMigrationEvent Handler which is invoked when an entity migrates from one host to another.
|
||||
//! @param handler The NotifyEntityMigrationEvent Handler to add
|
||||
virtual void AddNotifyEntityMigrationEventHandler(NotifyEntityMigrationEvent::Handler& handler) = 0;
|
||||
|
||||
//! Adds a ConnectionAcquiredEvent Handler which is invoked when a new endpoint connects to the session.
|
||||
//! @param handler The ConnectionAcquiredEvent Handler to add
|
||||
virtual void AddConnectionAcquiredHandler(ConnectionAcquiredEvent::Handler& handler) = 0;
|
||||
@@ -115,7 +135,18 @@ namespace Multiplayer
|
||||
//! @param handler The SessionShutdownEvent handler to add
|
||||
virtual void AddSessionShutdownHandler(SessionShutdownEvent::Handler& handler) = 0;
|
||||
|
||||
//! Sends a packet telling if entity update messages can be sent
|
||||
//! Signals a NotifyClientMigrationEvent with the provided parameters.
|
||||
//! @param hostId the host id of the host the client is migrating to
|
||||
//! @param userIdentifier the user identifier the client will provide the new host to validate identity
|
||||
//! @param lastClientInputId the last processed clientInputId by the current host
|
||||
virtual void SendNotifyClientMigrationEvent(const HostId& hostId, uint64_t userIdentifier, ClientInputId lastClientInputId) = 0;
|
||||
|
||||
//! Signals a NotifyEntityMigrationEvent with the provided parameters.
|
||||
//! @param entityHandle the network entity handle of the entity being migrated
|
||||
//! @param remoteHostId the host id of the host the entity is migrating to
|
||||
virtual void SendNotifyEntityMigrationEvent(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId) = 0;
|
||||
|
||||
//! Sends a packet telling if entity update messages can be sent.
|
||||
//! @param readyForEntityUpdates Ready for entity updates or not
|
||||
virtual void SendReadyForEntityUpdates(bool readyForEntityUpdates) = 0;
|
||||
|
||||
@@ -127,7 +158,7 @@ namespace Multiplayer
|
||||
//! @return the current server time in milliseconds
|
||||
virtual AZ::TimeMs GetCurrentHostTimeMs() const = 0;
|
||||
|
||||
//! Returns the current blend factor for client side interpolation
|
||||
//! Returns the current blend factor for client side interpolation.
|
||||
//! This value is only relevant on the client and is used to smooth between host frames
|
||||
//! @return the current blend factor
|
||||
virtual float GetCurrentBlendFactor() const = 0;
|
||||
@@ -146,9 +177,21 @@ namespace Multiplayer
|
||||
//! @param entityFilter non-owning pointer, the caller is responsible for memory management.
|
||||
virtual void SetFilterEntityManager(IFilterEntityManager* entityFilter) = 0;
|
||||
|
||||
//! @return pointer to the user-defined filtering manager of entities. By default, this isn't set and returns nullptr.
|
||||
//! Returns a pointer to the user-defined filtering manager of entities.
|
||||
//! @return pointer to the filtered entity manager, or nullptr if not set
|
||||
virtual IFilterEntityManager* GetFilterEntityManager() = 0;
|
||||
|
||||
//! Enables or disables automatic instantiation of netbound entities.
|
||||
//! This setting is controlled by the networking layer and should not be touched
|
||||
//! If enabled, netbound entities will instantiate as spawnables are loaded into the game world, generally true for the server
|
||||
//! If disabled, netbound entities will only stream from a host, always true for a client
|
||||
//! @param value boolean value controlling netbound entity instantiation behaviour
|
||||
virtual void SetShouldSpawnNetworkEntities(bool value) = 0;
|
||||
|
||||
//! Retrieves the current network entity instantiation behaviour.
|
||||
//! @return boolean true if netbound entities should be auto instantiated, false if not
|
||||
virtual bool GetShouldSpawnNetworkEntities() const = 0;
|
||||
|
||||
//! Retrieve the stats object bound to this multiplayer instance.
|
||||
//! @return the stats object bound to this multiplayer instance
|
||||
MultiplayerStats& GetStats() { return m_stats; }
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/RTTI/TypeSafeIntegral.h>
|
||||
#include <AzCore/std/string/fixed_string.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
#include <AzNetworking/Utilities/IpAddress.h>
|
||||
#include <AzNetworking/Serialization/ISerializer.h>
|
||||
#include <AzNetworking/ConnectionLayer/ConnectionEnums.h>
|
||||
#include <AzNetworking/DataStructures/ByteBuffer.h>
|
||||
@@ -25,8 +26,8 @@ namespace Multiplayer
|
||||
//! The default blend factor for ScopedAlterTime
|
||||
static constexpr float DefaultBlendFactor = 1.f;
|
||||
|
||||
AZ_TYPE_SAFE_INTEGRAL(HostId, uint32_t);
|
||||
static constexpr HostId InvalidHostId = static_cast<HostId>(-1);
|
||||
using HostId = AzNetworking::IpAddress;
|
||||
static const HostId InvalidHostId = HostId();
|
||||
|
||||
AZ_TYPE_SAFE_INTEGRAL(NetEntityId, uint32_t);
|
||||
static constexpr NetEntityId InvalidNetEntityId = static_cast<NetEntityId>(-1);
|
||||
@@ -105,9 +106,11 @@ namespace Multiplayer
|
||||
|
||||
struct EntityMigrationMessage
|
||||
{
|
||||
NetEntityId m_entityId;
|
||||
NetEntityId m_netEntityId;
|
||||
PrefabEntityId m_prefabEntityId;
|
||||
AzNetworking::PacketEncodingBuffer m_propertyUpdateData;
|
||||
bool operator!=(const EntityMigrationMessage& rhs) const;
|
||||
bool Serialize(AzNetworking::ISerializer& serializer);
|
||||
};
|
||||
|
||||
inline PrefabEntityId::PrefabEntityId(AZ::Name name, uint32_t entityOffset)
|
||||
@@ -133,9 +136,23 @@ namespace Multiplayer
|
||||
serializer.Serialize(m_entityOffset, "entityOffset");
|
||||
return serializer.IsValid();
|
||||
}
|
||||
|
||||
inline bool EntityMigrationMessage::operator!=(const EntityMigrationMessage& rhs) const
|
||||
{
|
||||
return m_netEntityId != rhs.m_netEntityId
|
||||
|| m_prefabEntityId != rhs.m_prefabEntityId
|
||||
|| m_propertyUpdateData != rhs.m_propertyUpdateData;
|
||||
}
|
||||
|
||||
inline bool EntityMigrationMessage::Serialize(AzNetworking::ISerializer& serializer)
|
||||
{
|
||||
serializer.Serialize(m_netEntityId, "netEntityId");
|
||||
serializer.Serialize(m_prefabEntityId, "prefabEntityId");
|
||||
serializer.Serialize(m_propertyUpdateData, "propertyUpdateData");
|
||||
return serializer.IsValid();
|
||||
}
|
||||
}
|
||||
|
||||
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostId);
|
||||
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::NetEntityId);
|
||||
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::NetComponentId);
|
||||
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::PropertyIndex);
|
||||
@@ -145,7 +162,6 @@ AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(Multiplayer::HostFrameId);
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
AZ_TYPE_INFO_SPECIALIZE(Multiplayer::HostId, "{D04B3363-8E1B-4193-8B2B-D2140389C9D5}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetEntityId, "{05E4C08B-3A1B-4390-8144-3767D8E56A81}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(Multiplayer::NetComponentId, "{8AF3B382-F187-4323-9014-B380638767E3}");
|
||||
AZ_TYPE_INFO_SPECIALIZE(Multiplayer::PropertyIndex, "{F4460210-024D-4B3B-A10A-04B669C34230}");
|
||||
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Multiplayer/IMultiplayer.h>
|
||||
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <Multiplayer/EntityDomains/IEntityDomain.h>
|
||||
#include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
|
||||
#include <Multiplayer/ReplicationWindows/IReplicationWindow.h>
|
||||
#include <AzNetworking/DataStructures/TimeoutQueue.h>
|
||||
#include <AzNetworking/PacketLayer/IPacketHeader.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/std/containers/deque.h>
|
||||
#include <AzCore/std/limits.h>
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
class IConnection;
|
||||
class IConnectionListener;
|
||||
}
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class IEntityDomain;
|
||||
class EntityReplicator;
|
||||
|
||||
using SendMigrateEntityEvent = AZ::Event<AzNetworking::IConnection&, const EntityMigrationMessage&>;
|
||||
|
||||
//! @class EntityReplicationManager
|
||||
//! @brief Handles replication of relevant entities for one connection.
|
||||
class EntityReplicationManager final
|
||||
{
|
||||
public:
|
||||
using EntityReplicatorMap = AZStd::map<NetEntityId, AZStd::unique_ptr<EntityReplicator>>;
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
Invalid,
|
||||
LocalServerToRemoteClient,
|
||||
LocalServerToRemoteServer,
|
||||
LocalClientToRemoteServer,
|
||||
};
|
||||
|
||||
EntityReplicationManager(AzNetworking::IConnection& connection, AzNetworking::IConnectionListener& connectionListener, Mode mode);
|
||||
~EntityReplicationManager() = default;
|
||||
|
||||
void SetRemoteHostId(const HostId& hostId);
|
||||
const HostId& GetRemoteHostId() const;
|
||||
|
||||
void ActivatePendingEntities();
|
||||
void SendUpdates();
|
||||
void Clear(bool forMigration);
|
||||
|
||||
bool SetEntityRebasing(NetworkEntityHandle& entityHandle);
|
||||
|
||||
void MigrateAllEntities();
|
||||
void MigrateEntity(NetEntityId netEntityId);
|
||||
bool CanMigrateEntity(const ConstNetworkEntityHandle& entityHandle) const;
|
||||
|
||||
bool HasRemoteAuthority(const ConstNetworkEntityHandle& entityHandle) const;
|
||||
|
||||
void SetRemoteEntityDomain(AZStd::unique_ptr<IEntityDomain> entityDomain);
|
||||
IEntityDomain* GetRemoteEntityDomain();
|
||||
void SetReplicationWindow(AZStd::unique_ptr<IReplicationWindow> replicationWindow);
|
||||
IReplicationWindow* GetReplicationWindow();
|
||||
|
||||
void GetEntityReplicatorIdList(AZStd::list<NetEntityId>& outList);
|
||||
uint32_t GetEntityReplicatorCount(NetEntityRole localNetworkRole);
|
||||
|
||||
void AddDeferredRpcMessage(NetworkEntityRpcMessage& rpcMessage);
|
||||
|
||||
void AddAutonomousEntityReplicatorCreatedHandler(AZ::Event<NetEntityId>::Handler& handler);
|
||||
void AddSendMigrateEntityEventHandler(SendMigrateEntityEvent::Handler& handler);
|
||||
|
||||
bool HandleEntityMigration(AzNetworking::IConnection* invokingConnection, EntityMigrationMessage& message);
|
||||
bool HandleEntityDeleteMessage(EntityReplicator* entityReplicator, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
|
||||
bool HandleEntityUpdateMessage(AzNetworking::IConnection* invokingConnection, const AzNetworking::IPacketHeader& packetHeader, const NetworkEntityUpdateMessage& updateMessage);
|
||||
bool HandleEntityRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& message);
|
||||
|
||||
AZ::TimeMs GetResendTimeoutTimeMs() const;
|
||||
|
||||
void SetMaxRemoteEntitiesPendingCreationCount(uint32_t maxPendingEntities);
|
||||
void SetEntityActivationTimeSliceMs(AZ::TimeMs timeSliceMs);
|
||||
void SetEntityPendingRemovalMs(AZ::TimeMs entityPendingRemovalMs);
|
||||
|
||||
AzNetworking::IConnection& GetConnection();
|
||||
AZ::TimeMs GetFrameTimeMs();
|
||||
|
||||
void AddReplicatorToPendingSend(const EntityReplicator& entityReplicator);
|
||||
|
||||
bool IsUpdateModeToServerClient();
|
||||
|
||||
private:
|
||||
AZ_DISABLE_COPY_MOVE(EntityReplicationManager);
|
||||
|
||||
enum class UpdateValidationResult
|
||||
{
|
||||
HandleMessage, // Handle an entity update message
|
||||
DropMessage, // Do not handle an entity update message, but don't disconnect (could be out of order/date and isn't relevant)
|
||||
DropMessageAndDisconnect, // Do not handle the message, it is malformed and we should disconnect the connection
|
||||
};
|
||||
|
||||
UpdateValidationResult ValidateUpdate(const NetworkEntityUpdateMessage& updateMessage, AzNetworking::PacketId packetId, EntityReplicator* entityReplicator);
|
||||
|
||||
using RpcMessages = AZStd::list<NetworkEntityRpcMessage>;
|
||||
bool DispatchOrphanedRpc(NetworkEntityRpcMessage& message, EntityReplicator* entityReplicator);
|
||||
|
||||
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
|
||||
EntityReplicatorList GenerateEntityUpdateList();
|
||||
|
||||
void SendEntityUpdateMessages(EntityReplicatorList& replicatorList);
|
||||
void SendEntityRpcs(RpcMessages& rpcMessages, bool reliable);
|
||||
|
||||
void MigrateEntityInternal(NetEntityId entityId);
|
||||
void OnEntityExitDomain(const ConstNetworkEntityHandle& entityHandle);
|
||||
void OnPostEntityMigration(const ConstNetworkEntityHandle& entityHandle, const HostId& remoteHostId);
|
||||
|
||||
EntityReplicator* AddEntityReplicator(const ConstNetworkEntityHandle& entityHandle, NetEntityRole netEntityRole);
|
||||
|
||||
const EntityReplicator* GetEntityReplicator(NetEntityId entityId) const;
|
||||
EntityReplicator* GetEntityReplicator(NetEntityId entityId);
|
||||
EntityReplicator* GetEntityReplicator(const ConstNetworkEntityHandle& entityHandle);
|
||||
|
||||
void UpdateWindow();
|
||||
|
||||
bool HandlePropertyChangeMessage
|
||||
(
|
||||
AzNetworking::IConnection* invokingConnection,
|
||||
EntityReplicator* entityReplicator,
|
||||
AzNetworking::PacketId packetId,
|
||||
NetEntityId netEntityId,
|
||||
NetEntityRole netEntityRole,
|
||||
AzNetworking::ISerializer& serializer,
|
||||
const PrefabEntityId& prefabEntityId
|
||||
);
|
||||
|
||||
void AddReplicatorToPendingRemoval(const EntityReplicator& replicator);
|
||||
void ClearRemovedReplicators();
|
||||
|
||||
class OrphanedEntityRpcs
|
||||
: public AzNetworking::ITimeoutHandler
|
||||
{
|
||||
public:
|
||||
OrphanedEntityRpcs(EntityReplicationManager& replicationManager);
|
||||
void Update();
|
||||
bool DispatchOrphanedRpcs(EntityReplicator& entityReplicator);
|
||||
void AddOrphanedRpc(NetEntityId entityId, NetworkEntityRpcMessage& entityRpcMessage);
|
||||
AZStd::size_t Size() const { return m_entityRpcMap.size(); }
|
||||
private:
|
||||
AzNetworking::TimeoutResult HandleTimeout(AzNetworking::TimeoutQueue::TimeoutItem& item) override;
|
||||
struct OrphanedRpcs
|
||||
{
|
||||
OrphanedRpcs() = default;
|
||||
OrphanedRpcs(OrphanedRpcs&& rhs)
|
||||
{
|
||||
m_rpcMessages.swap(rhs.m_rpcMessages);
|
||||
m_timeoutId = rhs.m_timeoutId;
|
||||
rhs.m_timeoutId = AzNetworking::TimeoutId{ 0 };
|
||||
}
|
||||
RpcMessages m_rpcMessages;
|
||||
AzNetworking::TimeoutId m_timeoutId = AzNetworking::TimeoutId{ 0 };
|
||||
};
|
||||
typedef AZStd::unordered_map<NetEntityId, OrphanedRpcs> EntityRpcMap;
|
||||
EntityRpcMap m_entityRpcMap;
|
||||
AzNetworking::TimeoutQueue m_timeoutQueue;
|
||||
EntityReplicationManager& m_replicationManager;
|
||||
};
|
||||
OrphanedEntityRpcs m_orphanedEntityRpcs;
|
||||
EntityReplicatorMap m_entityReplicatorMap;
|
||||
|
||||
//! The set of entities that we have sent creation messages for, but have not received confirmation back that the create has occurred
|
||||
AZStd::unordered_set<NetEntityId> m_remoteEntitiesPendingCreation;
|
||||
AZStd::deque<NetEntityId> m_entitiesPendingActivation;
|
||||
AZStd::set<NetEntityId> m_replicatorsPendingRemoval;
|
||||
AZStd::unordered_set<NetEntityId> m_replicatorsPendingSend;
|
||||
|
||||
// Deferred RPC Sends
|
||||
RpcMessages m_deferredRpcMessagesReliable;
|
||||
RpcMessages m_deferredRpcMessagesUnreliable;
|
||||
|
||||
AZ::Event<NetEntityId> m_autonomousEntityReplicatorCreated;
|
||||
EntityExitDomainEvent::Handler m_entityExitDomainEventHandler;
|
||||
SendMigrateEntityEvent m_sendMigrateEntityEvent;
|
||||
NotifyEntityMigrationEvent::Handler m_notifyEntityMigrationHandler;
|
||||
|
||||
AZ::ScheduledEvent m_clearRemovedReplicators;
|
||||
AZ::ScheduledEvent m_updateWindow;
|
||||
|
||||
AzNetworking::IConnectionListener& m_connectionListener;
|
||||
AzNetworking::IConnection& m_connection;
|
||||
AZStd::unique_ptr<IReplicationWindow> m_replicationWindow;
|
||||
AZStd::unique_ptr<IEntityDomain> m_remoteEntityDomain;
|
||||
|
||||
AZ::TimeMs m_entityActivationTimeSliceMs = AZ::TimeMs{ 0 };
|
||||
AZ::TimeMs m_entityPendingRemovalMs = AZ::TimeMs{ 0 };
|
||||
AZ::TimeMs m_frameTimeMs = AZ::TimeMs{ 0 };
|
||||
HostId m_remoteHostId = InvalidHostId;
|
||||
uint32_t m_maxRemoteEntitiesPendingCreationCount = AZStd::numeric_limits<uint32_t>::max();
|
||||
uint32_t m_maxPayloadSize = 0;
|
||||
Mode m_updateMode = Mode::Invalid;
|
||||
|
||||
friend class EntityReplicator;
|
||||
};
|
||||
}
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/Event.h>
|
||||
#include <AzCore/EBus/ScheduledEvent.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Component/EntityBus.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/containers/ring_buffer.h>
|
||||
#include <Multiplayer/Components/NetBindComponent.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
class IConnection;
|
||||
}
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class EntityReplicationManager;
|
||||
class NetworkEntityRpcMessage;
|
||||
class NetBindComponent;
|
||||
|
||||
class PropertyPublisher;
|
||||
class PropertySubscriber;
|
||||
|
||||
class EntityReplicator final
|
||||
: public AZ::EntityBus::Handler
|
||||
{
|
||||
public:
|
||||
EntityReplicator(EntityReplicationManager& replicationManager, AzNetworking::IConnection* connection, NetEntityRole remoteNetworkRole, const ConstNetworkEntityHandle& entityHandle);
|
||||
~EntityReplicator() override;
|
||||
|
||||
NetEntityRole GetBoundLocalNetworkRole() const;
|
||||
NetEntityRole GetRemoteNetworkRole() const;
|
||||
ConstNetworkEntityHandle GetEntityHandle() const;
|
||||
NetBindComponent* GetNetBindComponent();
|
||||
|
||||
void ActivateNetworkEntity();
|
||||
|
||||
const PrefabEntityId& GetPrefabEntityId() const;
|
||||
bool IsPrefabEntityIdSet() const;
|
||||
|
||||
bool OwnsReplicatorLifetime() const;
|
||||
bool RemoteManagerOwnsEntityLifetime() const;
|
||||
|
||||
// Interface for ReplicationManager to modify state of replication
|
||||
void Initialize(const ConstNetworkEntityHandle& entityHandle);
|
||||
void Reset(NetEntityRole remoteNetworkRole);
|
||||
void MarkForRemoval();
|
||||
bool IsMarkedForRemoval() const;
|
||||
void SetPendingRemoval(AZ::TimeMs pendingRemovalTimeMs);
|
||||
bool IsPendingRemoval() const;
|
||||
void ClearPendingRemoval();
|
||||
bool IsDeletionAcknowledged() const;
|
||||
bool WasMigrated() const;
|
||||
void SetWasMigrated(bool wasMigrated);
|
||||
// If an entity is part of a network hierarchy then it is only ready to activate when its direct parent entity is active.
|
||||
bool IsReadyToActivate() const;
|
||||
|
||||
NetworkEntityUpdateMessage GenerateUpdatePacket();
|
||||
void FinalizeSerialization(AzNetworking::PacketId sentId);
|
||||
|
||||
AZ::TimeMs GetResendTimeoutTimeMs() const;
|
||||
|
||||
PropertyPublisher* GetPropertyPublisher();
|
||||
const PropertyPublisher* GetPropertyPublisher() const;
|
||||
PropertySubscriber* GetPropertySubscriber();
|
||||
|
||||
// Handlers for Rpc messages
|
||||
bool HandleRpcMessage(AzNetworking::IConnection* invokingConnection, NetworkEntityRpcMessage& entityRpcMessage);
|
||||
|
||||
//! AZ::EntityBus overrides
|
||||
//! @{
|
||||
void OnEntityActivated(const AZ::EntityId&) override;
|
||||
void OnEntityDestroyed(const AZ::EntityId&) override;
|
||||
//! @}
|
||||
|
||||
private:
|
||||
enum class RpcValidationResult
|
||||
{
|
||||
HandleRpc, // Handle Rpc message
|
||||
DropRpc, // Do not handle Rpc
|
||||
DropRpcAndDisconnect, // Do not handle the Rpc, it is disallowed from this endpoint we should disconnect the connection
|
||||
ForwardToClient, // Forward this message to the Client
|
||||
ForwardToAutonomous, // Forward this message to the Autonomous
|
||||
ForwardToAuthority, // Forward this message to the Authority
|
||||
};
|
||||
RpcValidationResult ValidateRpcMessage(const NetworkEntityRpcMessage& entityRpcMessage) const;
|
||||
|
||||
// Internal state tracking
|
||||
bool CanSendUpdates();
|
||||
|
||||
void SetPrefabEntityId(const PrefabEntityId& prefabEntityId); // cache assetId so authority doesn't need to keep sending it
|
||||
|
||||
// Event processing
|
||||
void OnSendRpcEvent(NetworkEntityRpcMessage& message);
|
||||
void OnForwardRpcEvent(NetworkEntityRpcMessage& message);
|
||||
void OnEntityDirtiedEvent();
|
||||
void OnEntityRemovedEvent();
|
||||
void OnProxyRemovalTimedEvent();
|
||||
|
||||
void ActivateNetworkEntityInternal();
|
||||
|
||||
void AttachRPCHandlers();
|
||||
|
||||
void DeferRpcMessage(NetworkEntityRpcMessage& message);
|
||||
|
||||
AZ_DISABLE_COPY_MOVE(EntityReplicator);
|
||||
|
||||
// Events
|
||||
RpcSendEvent::Handler m_onSendRpcHandler;
|
||||
RpcSendEvent::Handler m_onForwardRpcHandler;
|
||||
RpcSendEvent::Handler m_onSendAutonomousRpcHandler;
|
||||
RpcSendEvent::Handler m_onForwardAutonomousRpcHandler;
|
||||
EntityDirtiedEvent::Handler m_onEntityDirtiedHandler;
|
||||
EntityStopEvent::Handler m_onEntityStopHandler;
|
||||
AZ::ScheduledEvent m_proxyRemovalEvent;
|
||||
|
||||
ConstNetworkEntityHandle m_entityHandle;
|
||||
PrefabEntityId m_prefabEntityId;
|
||||
|
||||
AZStd::unique_ptr<PropertyPublisher> m_propertyPublisher;
|
||||
AZStd::unique_ptr<PropertySubscriber> m_propertySubscriber;
|
||||
|
||||
NetBindComponent* m_netBindComponent = nullptr;
|
||||
EntityReplicationManager& m_replicationManager;
|
||||
AzNetworking::IConnection* m_connection;
|
||||
NetEntityRole m_boundLocalNetworkRole;
|
||||
NetEntityRole m_remoteNetworkRole;
|
||||
|
||||
bool m_wasMigrated = false;
|
||||
bool m_isForwardingRpc = false;
|
||||
bool m_prefabEntityIdSet = false;
|
||||
};
|
||||
}
|
||||
|
||||
#include <Multiplayer/NetworkEntity/EntityReplication/EntityReplicator.inl>
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
inline NetEntityRole EntityReplicator::GetBoundLocalNetworkRole() const
|
||||
{
|
||||
return m_boundLocalNetworkRole;
|
||||
}
|
||||
|
||||
inline NetEntityRole EntityReplicator::GetRemoteNetworkRole() const
|
||||
{
|
||||
return m_remoteNetworkRole;
|
||||
}
|
||||
|
||||
inline ConstNetworkEntityHandle EntityReplicator::GetEntityHandle() const
|
||||
{
|
||||
return m_entityHandle;
|
||||
}
|
||||
|
||||
inline NetBindComponent* EntityReplicator::GetNetBindComponent()
|
||||
{
|
||||
return m_netBindComponent;
|
||||
}
|
||||
|
||||
inline const PrefabEntityId& EntityReplicator::GetPrefabEntityId() const
|
||||
{
|
||||
AZ_Assert(IsPrefabEntityIdSet(), "PrefabEntityId not set for Entity");
|
||||
return m_prefabEntityId;
|
||||
}
|
||||
|
||||
inline bool EntityReplicator::IsPrefabEntityIdSet() const
|
||||
{
|
||||
return m_prefabEntityIdSet;
|
||||
}
|
||||
|
||||
inline bool EntityReplicator::WasMigrated() const
|
||||
{
|
||||
return m_wasMigrated;
|
||||
}
|
||||
|
||||
inline void EntityReplicator::SetWasMigrated(bool wasMigrated)
|
||||
{
|
||||
m_wasMigrated = wasMigrated;
|
||||
}
|
||||
|
||||
inline PropertyPublisher* EntityReplicator::GetPropertyPublisher()
|
||||
{
|
||||
return m_propertyPublisher.get();
|
||||
}
|
||||
|
||||
inline const PropertyPublisher* EntityReplicator::GetPropertyPublisher() const
|
||||
{
|
||||
return m_propertyPublisher.get();
|
||||
}
|
||||
|
||||
inline PropertySubscriber* EntityReplicator::GetPropertySubscriber()
|
||||
{
|
||||
return m_propertySubscriber.get();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ namespace Multiplayer
|
||||
class NetworkEntityAuthorityTracker;
|
||||
class NetworkEntityRpcMessage;
|
||||
class MultiplayerComponentRegistry;
|
||||
class IEntityDomain;
|
||||
|
||||
using EntityExitDomainEvent = AZ::Event<const ConstNetworkEntityHandle&>;
|
||||
using ControllersActivatedEvent = AZ::Event<const ConstNetworkEntityHandle&, EntityIsMigrating>;
|
||||
@@ -38,6 +39,19 @@ namespace Multiplayer
|
||||
|
||||
virtual ~INetworkEntityManager() = default;
|
||||
|
||||
//! Configures the NetworkEntityManager to operate as an authoritative host.
|
||||
//! @param hostId the hostId of this NetworkEntityManager
|
||||
//! @param entityDomain the entity domain used to determine which entities this manager has authority over
|
||||
virtual void Initialize(const HostId& hostId, AZStd::unique_ptr<IEntityDomain> entityDomain) = 0;
|
||||
|
||||
//! Returns whether or not the network entity manager has been initialized to host.
|
||||
//! @return boolean true if this network entity manager has been intialized to host
|
||||
virtual bool IsInitialized() const = 0;
|
||||
|
||||
//! Returns the entity domain associated with this network entity manager, this will be nullptr on clients.
|
||||
//! @return boolean the entity domain for this network entity manager
|
||||
virtual IEntityDomain* GetEntityDomain() const = 0;
|
||||
|
||||
//! Returns the NetworkEntityTracker for this INetworkEntityManager instance.
|
||||
//! @return the NetworkEntityTracker for this INetworkEntityManager instance
|
||||
virtual NetworkEntityTracker* GetNetworkEntityTracker() = 0;
|
||||
@@ -52,7 +66,7 @@ namespace Multiplayer
|
||||
|
||||
//! Returns the HostId for this INetworkEntityManager instance.
|
||||
//! @return the HostId for this INetworkEntityManager instance
|
||||
virtual HostId GetHostId() const = 0;
|
||||
virtual const HostId& GetHostId() const = 0;
|
||||
|
||||
//! Creates new entities of the given archetype
|
||||
//! @param prefabEntryId the name of the spawnable to spawn
|
||||
@@ -166,5 +180,8 @@ namespace Multiplayer
|
||||
//! Handle a local rpc message.
|
||||
//! @param entityRpcMessage the local rpc message to handle
|
||||
virtual void HandleLocalRpcMessage(NetworkEntityRpcMessage& message) = 0;
|
||||
|
||||
//! Visualization of network entity manager state.
|
||||
virtual void DebugDraw() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -30,18 +30,8 @@ namespace Multiplayer
|
||||
//! Constructs a ConstNetworkEntityHandle given an entity, an entity tracker
|
||||
//! @param entity pointer to the entity to construct a ConstNetworkEntityHandle for
|
||||
//! @param entityTracker pointer to the entity tracker that tracks the entity
|
||||
ConstNetworkEntityHandle(AZ::Entity* entity, const NetworkEntityTracker* entityTracker);
|
||||
|
||||
//! Constructs a ConstNetworkEntityHandle given an entity, a networkEntityId, and an entity tracker
|
||||
//! @param entity pointer to the entity to construct a ConstNetworkEntityHandle for
|
||||
//! @param netEntityId the networkEntityId of the entity
|
||||
//! @param entityTracker pointer to the entity tracker that tracks the entity
|
||||
ConstNetworkEntityHandle(AZ::Entity* entity, NetEntityId netEntityId, const NetworkEntityTracker* entityTracker);
|
||||
|
||||
//! Constructs a ConstNetworkEntityHandle given an entity, a networked entityId, an entity tracker, and a dirty version
|
||||
//! @param netBindComponent pointer to the entities NetBindComponent
|
||||
//! @param entityTracker pointer to the entity tracker that tracks the entity
|
||||
ConstNetworkEntityHandle(NetBindComponent* netBindComponent, const NetworkEntityTracker* entityTracker);
|
||||
//! can optionally be null in which case the entity tracker will be looked up
|
||||
ConstNetworkEntityHandle(AZ::Entity* entity, const NetworkEntityTracker* entityTracker = nullptr);
|
||||
|
||||
ConstNetworkEntityHandle(const ConstNetworkEntityHandle&) = default;
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ namespace Multiplayer
|
||||
// Non-serialized RPC metadata
|
||||
ReliabilityType m_isReliable = ReliabilityType::Reliable;
|
||||
};
|
||||
using NetworkEntityRpcVector = AZStd::fixed_vector<NetworkEntityRpcMessage, MaxAggregateRpcMessages>;
|
||||
|
||||
struct IRpcParamStruct
|
||||
{
|
||||
|
||||
@@ -118,4 +118,5 @@ namespace Multiplayer
|
||||
// This is to prevent blowing out stack memory if we declare an array of these EntityUpdateMessages
|
||||
AZStd::unique_ptr<AzNetworking::PacketEncodingBuffer> m_data;
|
||||
};
|
||||
using NetworkEntityUpdateVector = AZStd::fixed_vector<NetworkEntityUpdateMessage, MaxAggregateEntityMessages>;
|
||||
}
|
||||
|
||||
@@ -10,10 +10,14 @@
|
||||
|
||||
#include <Multiplayer/MultiplayerTypes.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityRpcMessage.h>
|
||||
#include <Multiplayer/NetworkEntity/NetworkEntityUpdateMessage.h>
|
||||
#include <AzCore/std/containers/map.h>
|
||||
|
||||
namespace Multiplayer
|
||||
{
|
||||
class EntityReplicator;
|
||||
|
||||
struct EntityReplicationData
|
||||
{
|
||||
EntityReplicationData() = default;
|
||||
@@ -21,6 +25,8 @@ namespace Multiplayer
|
||||
float m_priority = 0.0f;
|
||||
};
|
||||
using ReplicationSet = AZStd::map<ConstNetworkEntityHandle, EntityReplicationData>;
|
||||
using RpcMessages = AZStd::list<NetworkEntityRpcMessage>;
|
||||
using EntityReplicatorList = AZStd::deque<EntityReplicator*>;
|
||||
|
||||
class IReplicationWindow
|
||||
{
|
||||
@@ -33,6 +39,8 @@ namespace Multiplayer
|
||||
virtual uint32_t GetMaxProxyEntityReplicatorSendCount() const = 0;
|
||||
virtual bool IsInWindow(const ConstNetworkEntityHandle& entityPtr, NetEntityRole& outNetworkRole) const = 0;
|
||||
virtual void UpdateWindow() = 0;
|
||||
virtual AzNetworking::PacketId SendEntityUpdateMessages(NetworkEntityUpdateVector& entityUpdateVector) = 0;
|
||||
virtual void SendEntityRpcs(NetworkEntityRpcVector& entityRpcVector, bool reliable) = 0;
|
||||
virtual void DebugDraw() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user