Add RewindableArray and cleanup a bit more of vector

main
puvvadar 5 years ago
parent 50b9233552
commit d2797c0d15

@ -0,0 +1,46 @@
/*
* 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 <Multiplayer/NetworkTime/INetworkTime.h>
#include <Multiplayer/NetworkTime/RewindableObject.h>
#include <AzNetworking/Serialization/ISerializer.h>
#include <AzNetworking/ConnectionLayer/IConnection.h>
#include <AzNetworking/Utilities/NetworkCommon.h>
#include <AzCore/std/containers/array.h>
#include <AzCore/std/string/string.h>
#include <AzCore/Console/ILogger.h>
namespace Multiplayer
{
//! @class RewindableArray
//! @brief Data structure that has a compile-time upper bound, provides array semantics and supports network serialization
template <typename TYPE, uint32_t SIZE>
class RewindableArray
: public AZStd::array<RewindableObject<TYPE, Multiplayer::RewindHistorySize>, SIZE>
{
public:
//! Serialization method for array contained rewindable objects
//! @param serializer ISerializer instance to use for serialization
//! @return bool true for success, false for serialization failure
bool Serialize(AzNetworking::ISerializer& serializer);
//! Serialization method for array contained rewindable objects
//! @param serializer ISerializer instance to use for serialization
//! @param deltaRecord Bitset delta record used to detect state change during reconciliation
//! @return bool true for success, false for serialization failure
bool Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset &deltaRecord);
};
}
#include <Multiplayer/NetworkTime/RewindableArray.inl>

@ -0,0 +1,53 @@
/*
* 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
{
template <typename TYPE, uint32_t SIZE>
bool RewindableArray<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer)
{
for (uint32_t i = 0; i < size(); ++i)
{
if(!this[i].Serialize(serializer))
{
return false;
}
}
return serializer.IsValid();
}
template <typename TYPE, uint32_t SIZE>
bool RewindableArray<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset& deltaRecord)
{
for (uint32_t i = 0; i < size(); ++i)
{
if (deltaRecord.GetBit(i))
{
serializer.ClearTrackedChangesFlag();
if(!this[i].Serialize(serializer))
{
return false;
}
if ((serializer.GetSerializerMode() == AzNetworking::SerializerMode::WriteToObject) && !serializer.GetTrackedChangesFlag())
{
deltaRecord.SetBit(i, false);
}
}
}
return serializer.IsValid();
}
}

@ -43,12 +43,13 @@ namespace Multiplayer
//! Serialization method for fixed vector contained rewindable objects //! Serialization method for fixed vector contained rewindable objects
//! @param serializer ISerializer instance to use for serialization //! @param serializer ISerializer instance to use for serialization
//! @return bool true for success, false for serialization failure //! @return bool true for success, false for serialization failure
constexpr bool Serialize(AzNetworking::ISerializer& serializer); bool Serialize(AzNetworking::ISerializer& serializer);
//! Serialization method for fixed vector contained rewindable objects //! Serialization method for fixed vector contained rewindable objects
//! @param serializer ISerializer instance to use for serialization //! @param serializer ISerializer instance to use for serialization
//! @param deltaRecord Bitset delta record used to detect state change during reconciliation
//! @return bool true for success, false for serialization failure //! @return bool true for success, false for serialization failure
constexpr bool Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset &deltaRecord); bool Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset &deltaRecord);
//! Copies elements from the buffer pointed to by Buffer to this FixedSizeVector instance, vector size will be set to BufferSize //! Copies elements from the buffer pointed to by Buffer to this FixedSizeVector instance, vector size will be set to BufferSize
//! @param buffer pointer to the buffer to copy //! @param buffer pointer to the buffer to copy

@ -28,7 +28,7 @@ namespace Multiplayer
} }
template <typename TYPE, uint32_t SIZE> template <typename TYPE, uint32_t SIZE>
constexpr bool RewindableFixedVector<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer) bool RewindableFixedVector<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer)
{ {
m_rewindableSize = m_container.size(); m_rewindableSize = m_container.size();
if(!m_rewindableSize.Serialize(serializer) && !resize(m_rewindableSize)) if(!m_rewindableSize.Serialize(serializer) && !resize(m_rewindableSize))
@ -48,7 +48,7 @@ namespace Multiplayer
} }
template <typename TYPE, uint32_t SIZE> template <typename TYPE, uint32_t SIZE>
constexpr bool RewindableFixedVector<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset& deltaRecord) bool RewindableFixedVector<TYPE, SIZE>::Serialize(AzNetworking::ISerializer& serializer, AzNetworking::IBitset& deltaRecord)
{ {
if (deltaRecord.GetBit(SIZE)) if (deltaRecord.GetBit(SIZE))
{ {

@ -7,7 +7,11 @@
{% macro DeclareNetworkPropertyGetter(Property) %} {% macro DeclareNetworkPropertyGetter(Property) %}
{% set PropertyName = UpperFirst(Property.attrib['Name']) %} {% set PropertyName = UpperFirst(Property.attrib['Name']) %}
{% if Property.attrib['Container'] == 'Array' %} {% if Property.attrib['Container'] == 'Array' %}
const AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::k_RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Array() const; {% if Property.attrib['IsRewindable']|booleanTrue %}
const RewindableArray<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Array() const;
{% else %}
const AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> &Get{{ PropertyName }}Array() const;
{% endif %}
const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const; const {{ Property.attrib['Type'] }} &Get{{ PropertyName }}(int32_t index) const;
{% if Property.attrib['GenerateEventBindings']|booleanTrue %} {% if Property.attrib['GenerateEventBindings']|booleanTrue %}
void {{ PropertyName }}AddEvent(AZ::Event<int32_t, {{ Property.attrib['Type'] }}>::Handler& handler); void {{ PropertyName }}AddEvent(AZ::Event<int32_t, {{ Property.attrib['Type'] }}>::Handler& handler);
@ -160,7 +164,11 @@ AZ::Event<{{ Property.attrib['Type'] }}> m_{{ LowerFirst(Property.attrib['Name']
{% macro DeclareNetworkPropertyVars(Component, ReplicateFrom, ReplicateTo) %} {% macro DeclareNetworkPropertyVars(Component, ReplicateFrom, ReplicateTo) %}
{% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %} {% call(Property) AutoComponentMacros.ParseNetworkProperties(Component, ReplicateFrom, ReplicateTo) %}
{% if Property.attrib['Container'] == 'Array' %} {% if Property.attrib['Container'] == 'Array' %}
AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }}; {% if Property.attrib['IsRewindable']|booleanTrue %}
RewindableArray<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
{% else %}
AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
{% endif %}
{% elif Property.attrib['Container'] == 'Vector' %} {% elif Property.attrib['Container'] == 'Vector' %}
{% if Property.attrib['IsRewindable']|booleanTrue %} {% if Property.attrib['IsRewindable']|booleanTrue %}
RewindableFixedVector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }}; RewindableFixedVector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}> m_{{ LowerFirst(Property.attrib['Name']) }};
@ -236,6 +244,7 @@ AZStd::fixed_vector<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }
#include <Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h> #include <Multiplayer/NetworkEntity/EntityReplication/ReplicationRecord.h>
#include <Multiplayer/NetworkInput/IMultiplayerComponentInput.h> #include <Multiplayer/NetworkInput/IMultiplayerComponentInput.h>
#include <Multiplayer/NetworkInput/NetworkInput.h> #include <Multiplayer/NetworkInput/NetworkInput.h>
#include <Multiplayer/NetworkTime/RewindableArray.h>
#include <Multiplayer/NetworkTime/RewindableFixedVector.h> #include <Multiplayer/NetworkTime/RewindableFixedVector.h>
#include <Multiplayer/NetworkTime/RewindableObject.h> #include <Multiplayer/NetworkTime/RewindableObject.h>
{% call(Include) AutoComponentMacros.ParseIncludes(Component) %} {% call(Include) AutoComponentMacros.ParseIncludes(Component) %}

@ -3,7 +3,11 @@
{% macro LowerFirst(text) %}{{ text[0] | lower}}{{ text[1:] }}{% endmacro %} {% macro LowerFirst(text) %}{{ text[0] | lower}}{{ text[1:] }}{% endmacro %}
{% macro DefineNetworkPropertyGet(ClassName, Property, Prefix = '') %} {% macro DefineNetworkPropertyGet(ClassName, Property, Prefix = '') %}
{% if Property.attrib['Container'] == 'Array' %} {% if Property.attrib['Container'] == 'Array' %}
const AZStd::array<{% if Property.attrib['IsRewindable']|booleanTrue %}Multiplayer::RewindableObject<{% endif %}{{ Property.attrib['Type'] }}{% if Property.attrib['IsRewindable']|booleanTrue %}, Multiplayer::RewindHistorySize>{% endif %}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const {% if Property.attrib['IsRewindable']|booleanTrue %}
const RewindableArray<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const
{% else %}
const AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const
{% endif %}
{ {
return {{ Prefix }}m_{{ LowerFirst(Property.attrib['Name']) }}; return {{ Prefix }}m_{{ LowerFirst(Property.attrib['Name']) }};
} }
@ -643,7 +647,11 @@ void {{ ClassName }}::NotifyChanges{{ AutoComponentMacros.GetNetPropertiesSetNam
{% macro DefineArchetypePropertyGet(Property, ClassType, ClassName, Prefix = '') %} {% macro DefineArchetypePropertyGet(Property, ClassType, ClassName, Prefix = '') %}
{% if ClassType == '' or Property.attrib['ExportTo'] == ClassType or Property.attrib['ExportTo'] == "Common" %} {% if ClassType == '' or Property.attrib['ExportTo'] == ClassType or Property.attrib['ExportTo'] == "Common" %}
{% if Property.attrib['Container'] == 'Array' %} {% if Property.attrib['Container'] == 'Array' %}
{% if Property.attrib['IsRewindable']|booleanTrue %}
const RewindableArray<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const
{% else %}
const AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const const AZStd::array<{{ Property.attrib['Type'] }}, {{ Property.attrib['Count'] }}>& {{ ClassName }}::Get{{ UpperFirst(Property.attrib['Name']) }}Array() const
{% endif %}
{ {
return {{ Prefix }}m_{{ LowerFirst(Property.attrib['Name']) }}; return {{ Prefix }}m_{{ LowerFirst(Property.attrib['Name']) }};
} }
@ -1474,7 +1482,7 @@ namespace {{ Component.attrib['Namespace'] }}
{ {
{% for Property in Component.iter('NetworkProperty') %} {% for Property in Component.iter('NetworkProperty') %}
{% if Property.attrib['IsRewindable']|booleanTrue %} {% if Property.attrib['IsRewindable']|booleanTrue %}
{% if Property.attrib['Container'] == 'Vector' %} {% if Property.attrib['Container'] == 'Vector' or Property.attrib['Container'] == 'Array' %}
for ( auto& element: m_{{ LowerFirst(Property.attrib['Name']) }}) for ( auto& element: m_{{ LowerFirst(Property.attrib['Name']) }})
{ {
element.SetOwningConnectionId(connectionId); element.SetOwningConnectionId(connectionId);

@ -33,6 +33,8 @@ set(FILES
Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h Include/Multiplayer/NetworkInput/IMultiplayerComponentInput.h
Include/Multiplayer/NetworkInput/NetworkInput.h Include/Multiplayer/NetworkInput/NetworkInput.h
Include/Multiplayer/NetworkTime/INetworkTime.h Include/Multiplayer/NetworkTime/INetworkTime.h
Include/Multiplayer/NetworkTime/RewindableArray.h
Include/Multiplayer/NetworkTime/RewindableArray.inl
Include/Multiplayer/NetworkTime/RewindableFixedVector.h Include/Multiplayer/NetworkTime/RewindableFixedVector.h
Include/Multiplayer/NetworkTime/RewindableFixedVector.inl Include/Multiplayer/NetworkTime/RewindableFixedVector.inl
Include/Multiplayer/NetworkTime/RewindableObject.h Include/Multiplayer/NetworkTime/RewindableObject.h

Loading…
Cancel
Save