Many fixes for external gem multiplayer components and component network inputs, fixes an uninitialized variable resulting in continual desyncs, restructures our public includes to match the directory structure of source, allows autogen artefacts to be included by external gems, allowing for external multiplayer components to interact with multiplayer gem components with no extra code

This commit is contained in:
karlberg
2021-05-14 14:24:33 -07:00
parent 795aa114e6
commit 5acdc40595
73 changed files with 348 additions and 267 deletions
@@ -0,0 +1,113 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Source/AutoGen/LocalPredictionPlayerInputComponent.AutoComponent.h>
#include <Multiplayer/Components/NetBindComponent.h>
namespace Multiplayer
{
using CorrectionEvent = AZ::Event<>;
class LocalPredictionPlayerInputComponent
: public LocalPredictionPlayerInputComponentBase
{
public:
AZ_MULTIPLAYER_COMPONENT(Multiplayer::LocalPredictionPlayerInputComponent, s_localPredictionPlayerInputComponentConcreteUuid, Multiplayer::LocalPredictionPlayerInputComponentBase);
static void Reflect([[maybe_unused]] AZ::ReflectContext* context);
void OnInit() override;
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override;
};
class LocalPredictionPlayerInputComponentController
: public LocalPredictionPlayerInputComponentControllerBase
{
public:
LocalPredictionPlayerInputComponentController(LocalPredictionPlayerInputComponent& parent);
void OnActivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate([[maybe_unused]] Multiplayer::EntityIsMigrating entityIsMigrating) override;
void HandleSendClientInput
(
AzNetworking::IConnection* invokingConnection,
const Multiplayer::NetworkInputArray& inputArray,
const AZ::HashValue32& stateHash,
const AzNetworking::PacketEncodingBuffer& clientState
) override;
void HandleSendMigrateClientInput
(
AzNetworking::IConnection* invokingConnection,
const Multiplayer::NetworkInputMigrationVector& inputArray
) override;
void HandleSendClientInputCorrection
(
AzNetworking::IConnection* invokingConnection,
const Multiplayer::ClientInputId& inputId,
const AzNetworking::PacketEncodingBuffer& correction
) override;
//! Return true if we're currently replaying inputs after a correction.
//! If this value returns true, effects, audio, and other cosmetic triggers should be suppressed
//! @return true if we're within correction scope and replaying inputs
bool IsReplayingInput() const;
//! Return true if we're currently migrating from one host to another.
//! @return boolean true if we're currently migrating from one host to another
bool IsMigrating() const;
ClientInputId GetLastInputId() const;
HostFrameId GetInputFrameId(const NetworkInput& input) const;
void CorrectionEventAddHandle(CorrectionEvent::Handler& handler);
private:
void OnMigrateStart(ClientInputId migratedInputId);
void OnMigrateEnd();
void UpdateAutonomous(AZ::TimeMs deltaTimeMs);
void UpdateBankedTime(AZ::TimeMs deltaTimeMs);
// Implicitly sorted player input history, back() is the input that corresponds to the latest client input Id
NetworkInputHistory m_inputHistory;
// Anti-cheat accumulator for clients who purposely mess with their clock rate
NetworkInputArray m_lastInputReceived;
AZ::ScheduledEvent m_autonomousUpdateEvent; // Drives autonomous input collection
AZ::ScheduledEvent m_updateBankedTimeEvent; // Drives authority bank time updates
CorrectionEvent m_correctionEvent;
EntityMigrationStartEvent::Handler m_migrateStartHandler;
EntityMigrationEndEvent::Handler m_migrateEndHandler;
double m_moveAccumulator = 0.0;
double m_clientBankedTime = 0.0;
AZ::TimeMs m_lastInputReceivedTimeMs = AZ::TimeMs{ 0 };
AZ::TimeMs m_lastCorrectionSentTimeMs = AZ::TimeMs{ 0 };
ClientInputId m_clientInputId = ClientInputId{ 0 };
ClientInputId m_lastCorrectionInputId = ClientInputId{ 0 };
ClientInputId m_lastMigratedInputId = ClientInputId{ 0 }; // Used to resend inputs that were queued during a migration event
HostFrameId m_serverMigrateFrameId = InvalidHostFrameId;
bool m_replayingInput = false; // True if we're replaying inputs under a correction event (use this to suppress effects or audio)
bool m_allowMigrateClientInput = false; // True if this component was migrated, we will allow the client to send us migrated inputs (one time only)
};
}
@@ -15,7 +15,8 @@
#include <AzCore/Component/Component.h>
#include <AzNetworking/Serialization/ISerializer.h>
#include <AzNetworking/DataStructures/FixedSizeBitsetView.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/MultiplayerStats.h>
#include <Multiplayer/MultiplayerTypes.h>
#include <Multiplayer/IMultiplayer.h>
@@ -62,7 +63,10 @@ namespace Multiplayer
//! @}
NetEntityId GetNetEntityId() const;
NetEntityRole GetNetEntityRole() const;
bool IsAuthority() const;
bool IsAutonomous() const;
bool IsServer() const;
bool IsClient() const;
ConstNetworkEntityHandle GetEntityHandle() const;
NetworkEntityHandle GetEntityHandle();
void MarkDirty();
@@ -14,7 +14,8 @@
#include <AzCore/Name/Name.h>
#include <AzCore/std/containers/unordered_map.h>
#include <Multiplayer/MultiplayerComponent.h>
#include <Multiplayer/Components/MultiplayerComponent.h>
#include <Multiplayer/NetworkInput/IMultiplayerComponentInput.h>
namespace Multiplayer
{
@@ -22,13 +23,15 @@ namespace Multiplayer
{
public:
using PropertyNameLookupFunction = AZStd::function<const char*(PropertyIndex index)>;
using RpcNameLookupFunction = AZStd::function<const char* (RpcIndex index)>;
using RpcNameLookupFunction = AZStd::function<const char*(RpcIndex index)>;
using AllocComponentInputFunction = AZStd::function<AZStd::unique_ptr<IMultiplayerComponentInput>()>;
struct ComponentData
{
AZ::Name m_gemName;
AZ::Name m_componentName;
PropertyNameLookupFunction m_componentPropertyNameLookupFunction;
RpcNameLookupFunction m_componentRpcNameLookupFunction;
AllocComponentInputFunction m_allocComponentInputFunction;
};
//! Registers a multiplayer component with the multiplayer system.
@@ -36,6 +39,11 @@ namespace Multiplayer
//! @return the NetComponentId assigned to this particular component
NetComponentId RegisterMultiplayerComponent(const ComponentData& componentData);
//! Allocates a new component input for the provided netComponentId.
//! @param netComponentId the NetComponentId to allocate a component input for
//! @return pointer to the allocated component input, caller assumes ownership
AZStd::unique_ptr<IMultiplayerComponentInput> AllocateComponentInput(NetComponentId netComponentId);
//! Returns the gem name associated with the provided NetComponentId.
//! @param netComponentId the NetComponentId to return the gem name of
//! @return the name of the gem that contains the requested component
@@ -12,7 +12,7 @@
#pragma once
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <AzCore/Math/Aabb.h>
namespace Multiplayer
@@ -47,9 +47,13 @@ namespace Multiplayer
//! @return the networkId for the entity that owns this controller
NetEntityId GetNetEntityId() const;
//! Returns the networkRole for the entity that owns this controller.
//! @return the networkRole for the entity that owns this controller
NetEntityRole GetNetEntityRole() const;
//! Returns true if this controller has authority.
//! @return boolean true if this controller has authority
bool IsAuthority() const;
//! Returns true if this controller has autonomy (can locally predict).
//! @return boolean true if this controller has autonomy
bool IsAutonomous() const;
//! Returns the raw AZ::Entity pointer for the entity that owns this controller.
//! @return the raw AZ::Entity pointer for the entity that owns this controller
@@ -20,10 +20,10 @@
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzNetworking/Serialization/ISerializer.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <Multiplayer/ReplicationRecord.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/IMultiplayerComponentInput.h>
#include <Multiplayer/INetworkTime.h>
#include <Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/NetworkInput/IMultiplayerComponentInput.h>
#include <Multiplayer/NetworkTime/INetworkTime.h>
#include <Multiplayer/MultiplayerTypes.h>
#include <AzCore/EBus/Event.h>
@@ -63,12 +63,16 @@ namespace Multiplayer
NetEntityRole GetNetEntityRole() const;
bool IsAuthority() const;
bool IsAutonomous() const;
bool IsServer() const;
bool IsClient() const;
bool HasController() const;
NetEntityId GetNetEntityId() const;
const PrefabEntityId& GetPrefabEntityId() const;
ConstNetworkEntityHandle GetEntityHandle() const;
NetworkEntityHandle GetEntityHandle();
void SetAllowAutonomy(bool value);
MultiplayerComponentInputVector AllocateComponentInputs();
bool IsProcessingInput() const;
void CreateInput(NetworkInput& networkInput, float deltaTime);
@@ -155,6 +159,7 @@ namespace Multiplayer
bool m_isProcessingInput = false;
bool m_isMigrationDataValid = false;
bool m_needsToBeStopped = false;
bool m_allowAutonomy = false; // Set to true for the hosts controlled entity
friend class NetworkEntityManager;
friend class EntityReplicationManager;
@@ -0,0 +1,58 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include <Source/AutoGen/NetworkTransformComponent.AutoComponent.h>
#include <AzCore/Component/TransformBus.h>
namespace Multiplayer
{
class NetworkTransformComponent
: public NetworkTransformComponentBase
{
public:
AZ_MULTIPLAYER_COMPONENT(Multiplayer::NetworkTransformComponent, s_networkTransformComponentConcreteUuid, Multiplayer::NetworkTransformComponentBase);
static void Reflect(AZ::ReflectContext* context);
NetworkTransformComponent();
void OnInit() override;
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
private:
void OnRotationChangedEvent(const AZ::Quaternion& rotation);
void OnTranslationChangedEvent(const AZ::Vector3& translation);
void OnScaleChangedEvent(const AZ::Vector3& scale);
AZ::Event<AZ::Quaternion>::Handler m_rotationEventHandler;
AZ::Event<AZ::Vector3>::Handler m_translationEventHandler;
AZ::Event<AZ::Vector3>::Handler m_scaleEventHandler;
};
class NetworkTransformComponentController
: public NetworkTransformComponentControllerBase
{
public:
NetworkTransformComponentController(NetworkTransformComponent& parent);
void OnActivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
void OnDeactivate(Multiplayer::EntityIsMigrating entityIsMigrating) override;
private:
void OnTransformChangedEvent(const AZ::Transform& worldTm);
AZ::TransformChangedEvent::Handler m_transformChangedHandler;
};
}
@@ -12,7 +12,7 @@
#pragma once
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
namespace Multiplayer
@@ -12,7 +12,7 @@
#pragma once
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
namespace Multiplayer
{
@@ -15,8 +15,9 @@
#include <AzCore/RTTI/RTTI.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/DataStructures/ByteBuffer.h>
#include <Multiplayer/INetworkEntityManager.h>
#include <Multiplayer/INetworkTime.h>
#include <Multiplayer/Components/MultiplayerComponentRegistry.h>
#include <Multiplayer/NetworkEntity/INetworkEntityManager.h>
#include <Multiplayer/NetworkTime/INetworkTime.h>
#include <Multiplayer/MultiplayerStats.h>
namespace AzNetworking
@@ -101,28 +102,6 @@ namespace Multiplayer
//! @return pointer to the network entity manager instance bound to this multiplayer instance
virtual INetworkEntityManager* GetNetworkEntityManager() = 0;
//! Returns the gem name associated with the provided component index.
//! @param netComponentId the componentId to return the gem name of
//! @return the name of the gem that contains the requested component
virtual const char* GetComponentGemName(NetComponentId netComponentId) const = 0;
//! Returns the component name associated with the provided component index.
//! @param netComponentId the componentId to return the component name of
//! @return the name of the component
virtual const char* GetComponentName(NetComponentId netComponentId) const = 0;
//! Returns the property name associated with the provided component index and property index.
//! @param netComponentId the component index to return the property name of
//! @param propertyIndex the index of the network property to return the property name of
//! @return the name of the network property
virtual const char* GetComponentPropertyName(NetComponentId netComponentId, PropertyIndex propertyIndex) const = 0;
//! Returns the Rpc name associated with the provided component index and rpc index.
//! @param netComponentId the componentId to return the property name of
//! @param rpcIndex the index of the rpc to return the rpc name of
//! @return the name of the requested rpc
virtual const char* GetComponentRpcName(NetComponentId netComponentId, RpcIndex rpcIndex) 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; }
@@ -1,18 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
namespace Multiplayer
{
}
@@ -1,193 +0,0 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <Multiplayer/MultiplayerStats.h>
namespace Multiplayer
{
MultiplayerStats::Metric::Metric()
{
AZStd::uninitialized_fill_n(m_callHistory.data(), RingbufferSamples, 0);
AZStd::uninitialized_fill_n(m_byteHistory.data(), RingbufferSamples, 0);
}
void MultiplayerStats::ReserveComponentStats(NetComponentId netComponentId, uint16_t propertyCount, uint16_t rpcCount)
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
if (m_componentStats.size() <= netComponentIndex)
{
m_componentStats.resize(netComponentIndex + 1);
}
m_componentStats[netComponentIndex].m_propertyUpdatesSent.resize(propertyCount);
m_componentStats[netComponentIndex].m_propertyUpdatesRecv.resize(propertyCount);
m_componentStats[netComponentIndex].m_rpcsSent.resize(rpcCount);
m_componentStats[netComponentIndex].m_rpcsRecv.resize(rpcCount);
}
void MultiplayerStats::RecordPropertySent(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes)
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
const uint16_t propertyIndex = aznumeric_cast<uint16_t>(propertyId);
m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_totalCalls++;
m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_totalBytes += totalBytes;
m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_callHistory[m_recordMetricIndex]++;
m_componentStats[netComponentIndex].m_propertyUpdatesSent[propertyIndex].m_byteHistory[m_recordMetricIndex] += totalBytes;
}
void MultiplayerStats::RecordPropertyReceived(NetComponentId netComponentId, PropertyIndex propertyId, uint32_t totalBytes)
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
const uint16_t propertyIndex = aznumeric_cast<uint16_t>(propertyId);
m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_totalCalls++;
m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_totalBytes += totalBytes;
m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_callHistory[m_recordMetricIndex]++;
m_componentStats[netComponentIndex].m_propertyUpdatesRecv[propertyIndex].m_byteHistory[m_recordMetricIndex] += totalBytes;
}
void MultiplayerStats::RecordRpcSent(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes)
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
const uint16_t rpcIndex = aznumeric_cast<uint16_t>(rpcId);
m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_totalCalls++;
m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_totalBytes += totalBytes;
m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_callHistory[m_recordMetricIndex]++;
m_componentStats[netComponentIndex].m_rpcsSent[rpcIndex].m_byteHistory[m_recordMetricIndex] += totalBytes;
}
void MultiplayerStats::RecordRpcReceived(NetComponentId netComponentId, RpcIndex rpcId, uint32_t totalBytes)
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
const uint16_t rpcIndex = aznumeric_cast<uint16_t>(rpcId);
m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_totalCalls++;
m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_totalBytes += totalBytes;
m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_callHistory[m_recordMetricIndex]++;
m_componentStats[netComponentIndex].m_rpcsRecv[rpcIndex].m_byteHistory[m_recordMetricIndex] += totalBytes;
}
void MultiplayerStats::TickStats(AZ::TimeMs metricFrameTimeMs)
{
m_totalHistoryTimeMs = metricFrameTimeMs * static_cast<AZ::TimeMs>(RingbufferSamples);
m_recordMetricIndex = ++m_recordMetricIndex % RingbufferSamples;
for (ComponentStats& componentStats : m_componentStats)
{
for (Metric& metric : componentStats.m_propertyUpdatesSent)
{
metric.m_callHistory[m_recordMetricIndex] = 0;
metric.m_byteHistory[m_recordMetricIndex] = 0;
}
for (Metric& metric : componentStats.m_propertyUpdatesRecv)
{
metric.m_callHistory[m_recordMetricIndex] = 0;
metric.m_byteHistory[m_recordMetricIndex] = 0;
}
for (Metric& metric : componentStats.m_rpcsSent)
{
metric.m_callHistory[m_recordMetricIndex] = 0;
metric.m_byteHistory[m_recordMetricIndex] = 0;
}
for (Metric& metric : componentStats.m_rpcsRecv)
{
metric.m_callHistory[m_recordMetricIndex] = 0;
metric.m_byteHistory[m_recordMetricIndex] = 0;
}
}
}
static void CombineMetrics(MultiplayerStats::Metric& outArg1, const MultiplayerStats::Metric& arg2)
{
outArg1.m_totalCalls += arg2.m_totalCalls;
outArg1.m_totalBytes += arg2.m_totalBytes;
for (uint32_t index = 0; index < MultiplayerStats::RingbufferSamples; ++index)
{
outArg1.m_callHistory[index] += arg2.m_callHistory[index];
outArg1.m_byteHistory[index] += arg2.m_byteHistory[index];
}
}
static MultiplayerStats::Metric SumMetricVector(const AZStd::vector<MultiplayerStats::Metric>& metricVector)
{
MultiplayerStats::Metric result;
for (AZStd::size_t index = 0; index < metricVector.size(); ++index)
{
CombineMetrics(result, metricVector[index]);
}
return result;
}
MultiplayerStats::Metric MultiplayerStats::CalculateComponentPropertyUpdateSentMetrics(NetComponentId netComponentId) const
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
return SumMetricVector(m_componentStats[netComponentIndex].m_propertyUpdatesSent);
}
MultiplayerStats::Metric MultiplayerStats::CalculateComponentPropertyUpdateRecvMetrics(NetComponentId netComponentId) const
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
return SumMetricVector(m_componentStats[netComponentIndex].m_propertyUpdatesRecv);
}
MultiplayerStats::Metric MultiplayerStats::CalculateComponentRpcsSentMetrics(NetComponentId netComponentId) const
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
return SumMetricVector(m_componentStats[netComponentIndex].m_rpcsSent);
}
MultiplayerStats::Metric MultiplayerStats::CalculateComponentRpcsRecvMetrics(NetComponentId netComponentId) const
{
const uint16_t netComponentIndex = aznumeric_cast<uint16_t>(netComponentId);
return SumMetricVector(m_componentStats[netComponentIndex].m_rpcsRecv);
}
MultiplayerStats::Metric MultiplayerStats::CalculateTotalPropertyUpdateSentMetrics() const
{
Metric result;
for (AZStd::size_t index = 0; index < m_componentStats.size(); ++index)
{
const NetComponentId netComponentId = aznumeric_cast<NetComponentId>(index);
CombineMetrics(result, CalculateComponentPropertyUpdateSentMetrics(netComponentId));
}
return result;
}
MultiplayerStats::Metric MultiplayerStats::CalculateTotalPropertyUpdateRecvMetrics() const
{
Metric result;
for (AZStd::size_t index = 0; index < m_componentStats.size(); ++index)
{
const NetComponentId netComponentId = aznumeric_cast<NetComponentId>(index);
CombineMetrics(result, CalculateComponentPropertyUpdateRecvMetrics(netComponentId));
}
return result;
}
MultiplayerStats::Metric MultiplayerStats::CalculateTotalRpcsSentMetrics() const
{
Metric result;
for (AZStd::size_t index = 0; index < m_componentStats.size(); ++index)
{
const NetComponentId netComponentId = aznumeric_cast<NetComponentId>(index);
CombineMetrics(result, CalculateComponentRpcsSentMetrics(netComponentId));
}
return result;
}
MultiplayerStats::Metric MultiplayerStats::CalculateTotalRpcsRecvMetrics() const
{
Metric result;
for (AZStd::size_t index = 0; index < m_componentStats.size(); ++index)
{
const NetComponentId netComponentId = aznumeric_cast<NetComponentId>(index);
CombineMetrics(result, CalculateComponentRpcsRecvMetrics(netComponentId));
}
return result;
}
}
@@ -13,7 +13,7 @@
#pragma once
#include <Multiplayer/MultiplayerTypes.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <AzCore/Component/Entity.h>
#include <AzCore/EBus/Event.h>
#include <AzCore/Asset/AssetCommon.h>
@@ -138,4 +138,4 @@ namespace Multiplayer
};
}
#include <Multiplayer/NetworkEntityHandle.inl>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.inl>
@@ -28,7 +28,7 @@ namespace Multiplayer
{
public:
virtual ~IMultiplayerComponentInput() = default;
virtual NetComponentId GetComponentId() const = 0;
virtual NetComponentId GetNetComponentId() const = 0;
virtual bool Serialize(AzNetworking::ISerializer& serializer) = 0;
};
@@ -12,9 +12,9 @@
#pragma once
#include <Multiplayer/IMultiplayerComponentInput.h>
#include <Multiplayer/INetworkTime.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <Multiplayer/NetworkInput/IMultiplayerComponentInput.h>
#include <Multiplayer/NetworkTime/INetworkTime.h>
#include <AzCore/RTTI/TypeSafeIntegral.h>
namespace Multiplayer
@@ -57,15 +57,15 @@ namespace Multiplayer
IMultiplayerComponentInput* FindComponentInput(NetComponentId componentId);
template <class InputType>
const InputType* FindInput() const
const InputType* FindComponentInput() const
{
return static_cast<const InputType*>(FindInput(InputType::s_Type));
return static_cast<const InputType*>(FindComponentInput(InputType::s_netComponentId));
}
template <typename InputType>
InputType* FindInput()
InputType* FindComponentInput()
{
return static_cast<InputType*>(FindInput(InputType::s_Type));
return static_cast<InputType*>(FindComponentInput(InputType::s_netComponentId));
}
private:
@@ -12,7 +12,7 @@
#pragma once
#include <Multiplayer/INetworkTime.h>
#include <Multiplayer/NetworkTime/INetworkTime.h>
#include <AzNetworking/Serialization/ISerializer.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/Utilities/NetworkCommon.h>
@@ -115,4 +115,4 @@ namespace AZ
AZ_TYPE_INFO_TEMPLATE(Multiplayer::RewindableObject, "{B2937B44-FEE1-4277-B1E0-863DE76D363F}", AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_AUTO);
}
#include <Multiplayer/RewindableObject.inl>
#include <Multiplayer/NetworkTime/RewindableObject.inl>
@@ -13,7 +13,7 @@
#pragma once
#include <Multiplayer/MultiplayerTypes.h>
#include <Multiplayer/NetworkEntityHandle.h>
#include <Multiplayer/NetworkEntity/NetworkEntityHandle.h>
#include <AzCore/std/containers/unordered_map.h>
namespace Multiplayer