Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
@@ -0,0 +1,74 @@
/*
* 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 <AzCore/Preprocessor/Enum.h>
namespace AzNetworking
{
AZ_ENUM_CLASS(ReliabilityType
, Reliable
, Unreliable
);
AZ_ENUM_CLASS(TerminationEndpoint
, Local
, Remote
);
AZ_ENUM_CLASS(ConnectionRole
, Connector
, Acceptor
);
AZ_ENUM_CLASS(ConnectionState
, Disconnected
, Disconnecting
, Connected
, Connecting
);
AZ_ENUM_CLASS(DisconnectReason
, None
, Unknown
, StreamError
, NetworkError
, Timeout
, ConnectTimeout
, ConnectionRetry
, HeartbeatTimeout
, TransportError
, TerminatedByClient
, TerminatedByServer
, TerminatedByUser
, TerminatedByMultipleLogin
, RemoteHostClosedConnection
, ReliableTransportFailure
, ReliableQueueFull
, ConnectionRejected
, ConnectionDeleted
, ServerNotReady
, ServerError
, ClientMigrated
, SslFailure
, VersionMismatch
, NonceRejected
, DtlsHandshakeError
, MAX
);
AZ_ENUM_CLASS(ConnectResult
, Rejected // Connection attempt was rejected
, Accepted // Connection was accepted
);
}
@@ -0,0 +1,101 @@
/*
* 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 <AzNetworking/ConnectionLayer/ConnectionMetrics.h>
#include <AzNetworking/Utilities/NetworkCommon.h>
#include <AzCore/std/string/fixed_string.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/Console/ILogger.h>
namespace AzNetworking
{
AZ_CVAR(float, net_rttIncreaseOnPacketLoss, 1.2f, nullptr, AZ::ConsoleFunctorFlags::Null, "Scalar amount to increase round trip time estimates by on packet loss");
AZ_CVAR(AZ::TimeMs, net_maxPacketTrackTimeMs, AZ::TimeMs{2000}, nullptr, AZ::ConsoleFunctorFlags::Null, "Maximum time to track any particular packetid before giving up");
void DatarateMetrics::LogPacket(uint32_t byteCount, AZ::TimeMs currentTimeMs)
{
const AZ::TimeMs deltaTimeMs = currentTimeMs - m_lastLoggedTimeMs;
m_atoms[m_activeAtom].m_bytesTransmitted += byteCount;
m_atoms[m_activeAtom].m_timeAccumulatorMs += deltaTimeMs;
if (m_atoms[m_activeAtom].m_timeAccumulatorMs >= m_maxSampleTimeMs)
{
SwapBuffers();
}
m_lastLoggedTimeMs = currentTimeMs;
}
float DatarateMetrics::GetBytesPerSecond() const
{
const uint32_t sampleAtom = 1 - m_activeAtom;
if (m_atoms[sampleAtom].m_timeAccumulatorMs == AZ::TimeMs{0})
{
return 0.0f;
}
const float bytesLogged = float(m_atoms[sampleAtom].m_bytesTransmitted);
const float sampleTime = float(m_atoms[sampleAtom].m_timeAccumulatorMs);
return (bytesLogged * 1000.0f) / sampleTime; // (* 1000) to convert from bytes per millisecond to bytes per second
}
void ConnectionComputeRtt::LogPacketSent(PacketId packetId, AZ::TimeMs currentTimeMs)
{
for (uint32_t i = 0; i < MaxTrackableEntries; i++)
{
// Locate first unused entry, if one exists
if (m_entries[i].m_packetId == InvalidPacketId)
{
m_entries[i].m_packetId = packetId;
m_entries[i].m_sendTimeMs = currentTimeMs;
return;
}
}
}
void ConnectionComputeRtt::LogPacketAcked(PacketId packetId, AZ::TimeMs currentTimeMs)
{
for (uint32_t i = 0; i < MaxTrackableEntries; i++)
{
if (m_entries[i].m_packetId == packetId)
{
const AZ::TimeMs milliseconds(currentTimeMs - m_entries[i].m_sendTimeMs);
const float timeToAck = static_cast<float>(milliseconds) * 0.001f;
m_roundTripTime = (timeToAck * 0.1f) + (m_roundTripTime * 0.9f);
m_entries[i].m_packetId = InvalidPacketId;
AZLOG(NET_Rtt, "Packet id %d acked after %d milliseconds, new latency %f seconds", (int)packetId, (int)milliseconds, m_roundTripTime);
return;
}
else if ((m_entries[i].m_packetId != InvalidPacketId) && (currentTimeMs - m_entries[i].m_sendTimeMs > net_maxPacketTrackTimeMs))
{
AZLOG(NET_Rtt, "Giving up on tracking packetid %d, timeout exceeded", (int)m_entries[i].m_packetId);
m_entries[i].m_packetId = InvalidPacketId;
}
}
}
void ConnectionComputeRtt::LogPacketTimeout(PacketId packetId)
{
for (uint32_t i = 0; i < MaxTrackableEntries; i++)
{
if (m_entries[i].m_packetId == packetId)
{
m_roundTripTime *= net_rttIncreaseOnPacketLoss;
m_entries[i].m_packetId = InvalidPacketId;
return;
}
}
}
}
@@ -0,0 +1,135 @@
/*
* 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 <AzNetworking/Utilities/NetworkCommon.h>
#include <AzCore/Time/ITime.h>
namespace AzNetworking
{
//! @struct DatarateAtom
//! @brief basic unit for measuring socket datarate with connection to time.
struct DatarateAtom
{
DatarateAtom() = default;
uint32_t m_bytesTransmitted = 0;
AZ::TimeMs m_timeAccumulatorMs = AZ::TimeMs{0};
};
//! @class DatarateMetrics
//! @brief used to track datarate related metrics for a given connection with respect to time.
class DatarateMetrics
{
public:
DatarateMetrics() = default;
//! Constructor.
//! @param maxSampleTimeMs the period of time in milliseconds to attempt to smooth datarate over
DatarateMetrics(AZ::TimeMs maxSampleTimeMs);
//! Invoked whenever traffic is handled by the connection this instance is responsible for.
//! @param byteCount number of bytes sent through the connection
//! @param currentTimeMs current process time in milliseconds
void LogPacket(uint32_t byteCount, AZ::TimeMs currentTimeMs);
//! Retrieve a sample of the datarate being incurred by this connection in bytes per second.
//! @return datarate for traffic sent to or from the connection in bytes per second
float GetBytesPerSecond() const;
private:
//! Used internally to swap buffers used for metric gathering.
void SwapBuffers();
static constexpr AZ::TimeMs MaxSampleTimeMs = AZ::TimeMs{500};
AZ::TimeMs m_maxSampleTimeMs = MaxSampleTimeMs;
AZ::TimeMs m_lastLoggedTimeMs = MaxSampleTimeMs;
uint32_t m_activeAtom = 0;
DatarateAtom m_atoms[2];
};
//! @struct ConnectionPacketEntry
//! @brief basic data structure used to timestamp packet sequences.
struct ConnectionPacketEntry
{
ConnectionPacketEntry() = default;
//! Constructor.
//! @param packetId packet id of the packet this entry is tracking
//! @param sendTimeMs logged send time for the tracked packet in milliseconds
ConnectionPacketEntry(PacketId packetId, AZ::TimeMs sendTimeMs);
PacketId m_packetId = InvalidPacketId;
AZ::TimeMs m_sendTimeMs = AZ::TimeMs{0};
};
//! @class ConnectionComputeRtt
//! @brief helper class used to compute round trip time to an connection.
class ConnectionComputeRtt
{
public:
ConnectionComputeRtt() = default;
//! Invoked whenever traffic is sent through the connection this instance is responsible for.
//! @param packetId identifier of the packet being sent
//! @param currentTimeMs current process time in milliseconds
void LogPacketSent(PacketId packetId, AZ::TimeMs currentTimeMs);
//! Invoked whenever traffic is acknowledged from the connection this instance is responsible for.
//! @param packetId identifier of the packet being acked
//! @param currentTimeMs current process time in milliseconds
void LogPacketAcked(PacketId packetId, AZ::TimeMs currentTimeMs);
//! Invoked whenever traffic times out from the connection this instance is responsible for.
//! @param packetId identifier of the packet timing out
void LogPacketTimeout(PacketId packetId);
//! Retrieve a sample of the computed round trip time for this connection.
//! @return estimated round trip time (ping) for the given connection in seconds
float GetRoundTripTimeSeconds() const;
private:
static constexpr uint32_t MaxTrackableEntries = 4;
static constexpr float InitialRoundTripTime = 0.1f; //< Start off with a 100 millisecond estimate for Rtt
float m_roundTripTime = InitialRoundTripTime;
ConnectionPacketEntry m_entries[MaxTrackableEntries];
};
//! @struct ConnectionMetrics
//! @brief used to track general performance metrics for a given connection with respect to time.
struct ConnectionMetrics
{
ConnectionMetrics() = default;
ConnectionMetrics& operator=(const ConnectionMetrics& rhs) = default;
//! Resets all internal metrics to defaults.
void Reset();
uint32_t m_packetsSent = 0;
uint32_t m_packetsRecv = 0;
uint32_t m_packetsLost = 0;
uint32_t m_packetsAcked = 0;
DatarateMetrics m_sendDatarate;
DatarateMetrics m_recvDatarate;
ConnectionComputeRtt m_connectionRtt;
};
}
#include <AzNetworking/ConnectionLayer/ConnectionMetrics.inl>
@@ -0,0 +1,47 @@
/*
* 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 AzNetworking
{
inline DatarateMetrics::DatarateMetrics(AZ::TimeMs maxSampleTimeMs)
: m_maxSampleTimeMs(maxSampleTimeMs)
, m_lastLoggedTimeMs{0}
, m_activeAtom(0)
{
;
}
inline void DatarateMetrics::SwapBuffers()
{
m_activeAtom = 1 - m_activeAtom;
m_atoms[m_activeAtom] = DatarateAtom();
}
inline ConnectionPacketEntry::ConnectionPacketEntry(PacketId packetId, AZ::TimeMs sendTimeMs)
: m_packetId(packetId)
, m_sendTimeMs(sendTimeMs)
{
;
}
inline float ConnectionComputeRtt::GetRoundTripTimeSeconds() const
{
return m_roundTripTime;
}
inline void ConnectionMetrics::Reset()
{
*this = ConnectionMetrics();
}
}
@@ -0,0 +1,131 @@
/*
* 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 <AzCore/Time/ITime.h>
#include <AzNetworking/Utilities/IpAddress.h>
#include <AzNetworking/ConnectionLayer/ConnectionEnums.h>
#include <AzNetworking/ConnectionLayer/ConnectionMetrics.h>
namespace AzNetworking
{
// Forwards
class IPacket;
//! This is a strong typedef for representing a remote host that may be triggering time changes for backward reconciliation.
AZ_TYPE_SAFE_INTEGRAL(ConnectionId, uint32_t);
static constexpr ConnectionId InvalidConnectionId = ConnectionId{ 0xFFFFFFFF };
struct ConnectionQuality
{
ConnectionQuality() = default;
ConnectionQuality(int32_t lossPercentage, AZ::TimeMs latencyMs, AZ::TimeMs varianceMs);
int32_t m_lossPercentage = 0;
AZ::TimeMs m_latencyMs = AZ::TimeMs{ 0 };
AZ::TimeMs m_varianceMs = AZ::TimeMs{ 0 };
};
enum class TrustZone
{
ExternalClientToServer // This connection is potentially opened to external and untrusted machines
, InternalServerToServer // This connection is only ever used for trusted server to server communication
};
//! @class IConnection
//! @brief interface class for network connections.
class IConnection
{
public:
//! Construct with a specific connectionId and remoteAddress.
//! @param connectionId the connection identifier to use for this connection
//! @param address the remote address this connection
IConnection(ConnectionId connectionId, const IpAddress& address);
virtual ~IConnection() = default;
//! A helper function that transmits a packet on this connection reliably.
//! @param packet packet to transmit
//! @return boolean true if the packet was transmitted (not an indication of delivery)
virtual bool SendReliablePacket(const IPacket& packet) = 0;
//! A helper function that transmits a packet on this connection unreliably.
//! @param packet packet to transmit
//! @return the unreliable packet identifier of the transmitted packet
virtual PacketId SendUnreliablePacket(const IPacket& packet) = 0;
//! Returns true if the given packet id was confirmed acknowledged by the remote endpoint, false otherwise.
//! @param packetId the packet id of the packet to confirm acknowledgment of
//! @return boolean true if the packet is confirmed acknowledged, false if the packet number is out of range, lost, or still pending acknowledgment
virtual bool WasPacketAcked(PacketId packetId) const = 0;
//! Retrieves the connection state for this IConnection instance.
//! @return the current connection state for this IConnection instance
virtual ConnectionState GetConnectionState() const = 0;
//! Retrieves the connection role of this connection instance, whether it was initiated or accepted.
//! @return whether this connection was initiated or accepted
virtual ConnectionRole GetConnectionRole() const = 0;
//! Disconnects the connection with the provided termination reason
//! @param reason reason for the disconnect
//! @param endpoint which endpoint initiated the disconnect, local or remote
//! @return boolean true on success
virtual bool Disconnect(DisconnectReason reason, TerminationEndpoint endpoint) = 0;
//! Sets connection maximum transmission unit for this connection.
//! Currently unsupported on TcpConnections
//! @param connectionMtu the max transmission unit for this connection
virtual void SetConnectionMtu(uint32_t connectionMtu) = 0;
//! Returns the connection maximum transmission unit.
//! Currently unsupported on TcpConnections
//! @return the max transmission unit for this connection
virtual uint32_t GetConnectionMtu() const = 0;
//! Sets connection quality values for testing poor connection conditions.
//! Currently unsupported on TcpConnections
//! @param connectionQuality simulated connection quality values to use
virtual void SetConnectionQuality(const ConnectionQuality& connectionQuality) = 0;
//! Returns the connection identifier for this connection instance.
//! @return the connection identifier for this connection instance
ConnectionId GetConnectionId() const;
//! Sets the remote address for this connection instance.
//! @param address the remote address to use for this connection instance
void SetRemoteAddress(const IpAddress& address);
//! Returns the remote address for this connection instance.
//! @return the remote address for this connection instance
const IpAddress& GetRemoteAddress() const;
//! Retrieves connection metric info.
//! @return reference to the connection metric info
const ConnectionMetrics& GetMetrics() const;
//! Retrieves connection metric info, non-const.
//! @return reference to the connection metric info
ConnectionMetrics& GetMetrics();
private:
// The following data members are here in the interface for performance reasons
ConnectionId m_connectionId;
IpAddress m_remoteAddress;
ConnectionMetrics m_connectionMetrics;
};
}
#include <AzNetworking/ConnectionLayer/IConnection.inl>
@@ -0,0 +1,56 @@
/*
* 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 AzNetworking
{
inline ConnectionQuality::ConnectionQuality(int32_t lossPercentage, AZ::TimeMs latencyMs, AZ::TimeMs varianceMs)
: m_lossPercentage(lossPercentage)
, m_latencyMs(latencyMs)
, m_varianceMs(varianceMs)
{
;
}
inline IConnection::IConnection(ConnectionId connectionId, const IpAddress& address)
: m_connectionId(connectionId)
, m_remoteAddress(address)
{
;
}
inline ConnectionId IConnection::GetConnectionId() const
{
return m_connectionId;
}
inline void IConnection::SetRemoteAddress(const IpAddress& address)
{
m_remoteAddress = address;
}
inline const IpAddress& IConnection::GetRemoteAddress() const
{
return m_remoteAddress;
}
inline const ConnectionMetrics& IConnection::GetMetrics() const
{
return m_connectionMetrics;
}
inline ConnectionMetrics& IConnection::GetMetrics()
{
return m_connectionMetrics;
}
}
@@ -0,0 +1,61 @@
/*
* 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 <AzNetworking/Utilities/IpAddress.h>
#include <AzNetworking/PacketLayer/IPacket.h>
#include <AzNetworking/PacketLayer/IPacketHeader.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/ConnectionLayer/ConnectionEnums.h>
namespace AzNetworking
{
//! @class IConnectionListener
//! @brief interface class for application layer dealing with connection level events.
class IConnectionListener
{
public:
virtual ~IConnectionListener() = default;
//! Invoked to validate any new incoming connection from a new endpoint.
//! @param remoteAddress the address of the remote endpoint initiating a connection
//! @param packetHeader packet header of the associated payload
//! @param serializer serializer instance containing the transmitted payload
//! @return the result of the application layers validation of the connect message
virtual ConnectResult ValidateConnect(const IpAddress& remoteAddress, const IPacketHeader& packetHeader, ISerializer& serializer) = 0;
//! Invoked when a new connection is successfully established.
//! @param connection pointer to the new connection instance
virtual void OnConnect(IConnection* connection) = 0;
//! Called on receipt of a packet from a connected connection.
//! @param connection pointer to the connection instance generating the event
//! @param packetHeader packet header of the associated payload
//! @param serializer serializer instance containing the transmitted payload
//! @return boolean true to signal success, false to disconnect with a transport error
virtual bool OnPacketReceived(IConnection* connection, const IPacketHeader& packetHeader, ISerializer& serializer) = 0;
//! Called when a packet is deemed lost by the remote connection.
//! @param connection pointer to the connection instance generating the event
//! @param packetId identifier of the lost packet
virtual void OnPacketLost(IConnection* connection, PacketId packetId) = 0;
//! Called on disconnection from an connection.
//! @param connection pointer to the connection instance generating the event
//! @param reason reason for the disconnect
//! @param endpoint whether the disconnection was initiated locally or remotely
virtual void OnDisconnect(IConnection* connection, DisconnectReason reason, TerminationEndpoint endpoint) = 0;
};
}
@@ -0,0 +1,51 @@
/*
* 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 <AzNetworking/ConnectionLayer/IConnection.h>
namespace AzNetworking
{
//! @class IConnectionSet
//! @brief interface class for managing a set of connections.
class IConnectionSet
{
public:
using ConnectionVisitor = AZStd::function<void(IConnection&)>;
virtual ~IConnectionSet() = default;
//! Will visit each active connection in the connection set and invoke the provided connection visitor.
//! @param visitor the visitor to visit each connection with
virtual void VisitConnections(const ConnectionVisitor& visitor) = 0;
//! Deletes a connection from this connection list instance by connection identifier.
//! @param connectionId connection identifier of the connection to delete
//! @return boolean true on success
virtual bool DeleteConnection(ConnectionId connectionId) = 0;
//! Retrieves a connection from this connection set by connection identifier.
//! @param connectionId connection identifier of the connection to retrieve
//! @return pointer to the requested connection instance on success, nullptr on failure
virtual IConnection* GetConnection(ConnectionId connectionId) const = 0;
//! Returns the next valid connection identifier for this connection list instance.
//! @return a valid connection identifier to give a new connection instance, or InvalidConnectionId on failure
virtual ConnectionId GetNextConnectionId() = 0;
//! Returns the current total connection count for this connection set
//! @return the current total connection count for this connection set
virtual uint32_t GetConnectionCount() const = 0;
};
}
@@ -0,0 +1,59 @@
/*
* 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 <AzCore/RTTI/TypeSafeIntegral.h>
namespace AzNetworking
{
AZ_TYPE_SAFE_INTEGRAL(SequenceId, uint16_t);
static constexpr SequenceId InvalidSequenceId = SequenceId{uint16_t(0xFFFF)};
//! Helper method that compares wrap-around sequence values to determine if one is more recent than another.
//! @param input1 first sequence value to compare against
//! @param input2 second sequence value to compare against
//! @return boolean true if input1 represents a newer sequence value than input2
template <typename TYPE>
bool SequenceMoreRecent(TYPE input1, TYPE input2);
//! Helper method that returns true when the sequences appears to have wrapped around.
//! @param input1 first sequence value to compare against
//! @param input2 second sequence value to compare against
//! @return boolean true if input1 represents a newer sequence value than input2 and input1 is numerically less than input2
template <typename TYPE>
bool SequenceRolledOver(TYPE input1, TYPE input2);
//! @class SequenceGenerator
//! @brief Generates wrapping sequence numbers.
class SequenceGenerator
{
public:
SequenceGenerator() = default;
//! Resets the sequence generator instance.
void Reset();
//! Returns the next sequence id for this generator instance.
//! @return the next sequence id for this generator instance
SequenceId GetNextSequenceId();
private:
SequenceId m_nextSequenceId = InvalidSequenceId;
};
}
AZ_TYPE_SAFE_INTEGRAL_SERIALIZEBINDING(AzNetworking::SequenceId);
#include <AzNetworking/ConnectionLayer/SequenceGenerator.inl>
@@ -0,0 +1,48 @@
/*
* 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 AzNetworking
{
template <typename TYPE>
inline bool SequenceMoreRecent(TYPE input1, TYPE input2)
{
constexpr TYPE HalfMaxSequence = static_cast<TYPE>(static_cast<TYPE>(~0) >> 1);
return ((input1 > input2) && (input1 - input2 <= HalfMaxSequence)) ||
((input2 > input1) && (input2 - input1 > HalfMaxSequence));
}
template <typename TYPE>
inline bool SequenceRolledOver(TYPE input1, TYPE input2)
{
constexpr TYPE HalfMaxSequence = static_cast<TYPE>(static_cast<TYPE>(~0) >> 1);
return (input2 > input1) && (input2 - input1 > HalfMaxSequence);
}
inline void SequenceGenerator::Reset()
{
m_nextSequenceId = InvalidSequenceId;
}
inline SequenceId SequenceGenerator::GetNextSequenceId()
{
++m_nextSequenceId;
if (m_nextSequenceId == InvalidSequenceId)
{
++m_nextSequenceId;
}
return m_nextSequenceId;
}
}