Fixing some dependencies in script canvas and emfx

This commit is contained in:
karlberg
2021-05-11 13:42:44 -07:00
parent 3e13dd52d1
commit 5440d0926d
12 changed files with 1 additions and 1521 deletions
@@ -1,448 +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 "EMotionFX_precompiled.h"
#include <Integration/Components/AnimGraphNetSyncComponent.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/SerializeContext.h>
#include <GridMate/Replica/ReplicaFunctions.h>
#include <GridMate/Serialize/MathMarshal.h>
#include <AzFramework/Network/NetBindingHandlerBus.h>
namespace EMotionFX
{
namespace Integration
{
namespace Network
{
/**
* \brief This is a GridMate chunk that replicates Anim Graph parameters.
* It's challenge is to replicate any of the supported parameter types where
* the types are only known at runtime. To solve that, many datasets are created
* with helper macros to avoid code duplication (@PARAM_DATASET and @PARAM_DATASET_NAME).
*
* For maximum compression, one should build a custom component that specifies the anim graph parameters by hand, for example:
*
* DataSet<float> m_param0;
*
* or if using delta compression feature of GridMate:
*
* DeltaCompressedDataSet<float, 1> m_param1;
*
* Active nodes (@m_activeNodes) change infrequently.
*
* Warning: @m_motionNodes motion nodes often do change frequently as their motion play time ticks down.
* Care must be applied when aiming for the network budget of a project.
*/
class AnimGraphNetSyncComponent::Chunk : public GridMate::ReplicaChunkBase
{
public:
GM_CLASS_ALLOCATOR(Chunk);
Chunk() : m_activeNodes("Active Nodes", NodeIndexContainer{}), m_motionNodes("Motion Nodes", MotionNodePlaytimeContainer{}) {}
static const char* GetChunkName() { return "AnimGraphNetSyncComponent::Chunk"; }
bool IsReplicaMigratable() override { return true; }
using AnimDataSetType = GridMate::DataSet<AnimParameter, AnimParameterMarshaler, AnimParameterThrottler>;
template <void (AnimGraphNetSyncComponent::* CallbackMethod)(const AnimParameter&, const GridMate::TimeContext&)>
using AnimDataSet = AnimDataSetType::BindInterface<AnimGraphNetSyncComponent, CallbackMethod>;
// A helper macro that creates a variable like this one:
// AnimDataSet<&AnimGraphNetSyncComponent::OnAnimParameterChanged<0>> m_parameter0 = { "Param 0" };
#define PARAM_DATASET( N ) AnimDataSet<&AnimGraphNetSyncComponent::OnAnimParameterChanged< N >> m_parameter##N = { "Param " #N }
PARAM_DATASET(0);
PARAM_DATASET(1);
PARAM_DATASET(2);
PARAM_DATASET(3);
PARAM_DATASET(4);
PARAM_DATASET(5);
PARAM_DATASET(6);
PARAM_DATASET(7);
PARAM_DATASET(8);
PARAM_DATASET(9);
/*
* Note: GridMate by default supports up to 32 DataSets per ReplicaChunk: @GM_MAX_DATASETS_IN_CHUNK.
* That means that a component can sync up to 32 separate network fields. One can vary the number of supported number
* of parameters by simply creating new entries of @PARAM_DATASET above and @PARAM_DATASET_NAME below.
*/
// A collection of datasets that are used to synchronize anim graph parameters.
AZStd::array<AnimDataSetType*, 10> m_parameters = { { // clang pre-6.0 requires double "{{" here but doesn't perform compile length verification :(
&m_parameter0,
&m_parameter1,
&m_parameter2,
&m_parameter3,
&m_parameter4,
&m_parameter5,
&m_parameter6,
&m_parameter7,
&m_parameter8,
&m_parameter9,
} };
GridMate::DataSet<NodeIndexContainer, NodeIndexContainerMarshaler>::
BindInterface<AnimGraphNetSyncComponent, &AnimGraphNetSyncComponent::OnActiveNodesChanged> m_activeNodes;
GridMate::DataSet<MotionNodePlaytimeContainer, MotionNodePlaytimeContainerMarshaler>::
BindInterface<AnimGraphNetSyncComponent, &AnimGraphNetSyncComponent::OnMotionNodesChanged> m_motionNodes;
};
void AnimGraphNetSyncComponent::Reflect(AZ::ReflectContext* context)
{
GridMate::ReplicaChunkDescriptorTable& descTable = GridMate::ReplicaChunkDescriptorTable::Get();
if (!descTable.FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(Chunk::GetChunkName())))
{
descTable.RegisterChunkType<Chunk>();
}
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
if (serializeContext)
{
serializeContext->Class<AnimGraphNetSyncComponent, AZ::Component>()
->Version(1)
->Field( "Sync parameters", &AnimGraphNetSyncComponent::m_syncParameters )
->Field( "Sync active nodes", &AnimGraphNetSyncComponent::m_syncActiveNodes )
->Field( "Sync motion nodes", &AnimGraphNetSyncComponent::m_syncMotionNodes )
;
AZ::EditContext* editContent = serializeContext->GetEditContext();
if (editContent)
{
editContent->Class<AnimGraphNetSyncComponent>("Anim Graph Net Sync",
"Replicates anim graph parameters over the network using GridMate")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c))
->Attribute(AZ::Edit::Attributes::Category, "Networking")
->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/AnimGraphNetSync.svg")
->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncParameters, "Sync parameters",
"Synchronize parameters of the anim graph on the entity" )
->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncActiveNodes, "Sync active nodes",
"Synchronize active nodes in the anim graph on the entity" )
->DataElement( AZ::Edit::UIHandlers::Default, &AnimGraphNetSyncComponent::m_syncMotionNodes, "Sync motion nodes",
"Synchronize motion nodes in the anim graph on the entity. Warning: this may take a significant amount of network bandwidth" )
;
}
}
}
void AnimGraphNetSyncComponent::Activate()
{
AnimGraphComponentNotificationBus::Handler::BusConnect(GetEntityId());
if (m_syncMotionNodes || m_syncActiveNodes) // if there is anything synchronize over the network
{
const bool isAuthoritative = AzFramework::NetQuery::IsEntityAuthoritative(GetEntityId());
if (isAuthoritative)
{
// Only the server (or authoritative entity) needs to watch the nodes values.
AZ::TickBus::Handler::BusConnect();
}
// We need to get anim graph instance. It will be either available to us now or later via a notification bus. See @OnAnimGraphInstanceCreated
AnimGraphComponentRequestBus::EventResult(m_instance, GetEntityId(), &AnimGraphComponentRequestBus::Events::GetAnimGraphInstance);
if (m_instance)
{
if (!m_instance->GetSnapshot())
{
m_instance->CreateSnapshot(isAuthoritative);
}
}
}
}
void AnimGraphNetSyncComponent::Deactivate()
{
AnimGraphComponentNotificationBus::Handler::BusDisconnect();
AZ::TickBus::Handler::BusDisconnect();
}
void AnimGraphNetSyncComponent::SetParameterOnClient(const AnimParameter& value, AZ::u8 index)
{
switch (value.m_type)
{
case AnimParameter::Type::Unsupported:
break;
case AnimParameter::Type::Float:
AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterFloat, index, value.m_value.f);
break;
case AnimParameter::Type::Bool:
AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterBool, index, value.m_value.b);
break;
case AnimParameter::Type::Vector2:
AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterVector2, index, value.m_value.v2);
break;
case AnimParameter::Type::Vector3:
AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterVector3, index, value.m_value.v3);
break;
case AnimParameter::Type::Quaternion:
AnimGraphComponentRequestBus::Event(GetEntityId(), &AnimGraphComponentRequestBus::Events::SetParameterRotation, index, value.m_value.q);
break;
default:
AZ_Assert(false, "Unsupported type");
break;
}
}
template <AZ::u8 Index>
void AnimGraphNetSyncComponent::OnAnimParameterChanged(const AnimParameter& value, const GridMate::TimeContext&)
{
SetParameterOnClient(value, Index);
}
template <AnimParameter::Type AnimParameterType, typename FieldType>
void AnimGraphNetSyncComponent::SetParameterOnServer(AZ::u8 parameterIndex, const FieldType& newValue)
{
if (m_syncParameters)
{
if (Chunk* chunk = GetChunk())
{
if (parameterIndex < chunk->m_parameters.size())
{
AnimParameter param;
param.m_type = AnimParameterType;
static_assert(sizeof(FieldType) <= sizeof(param.m_value), "The largest value param.m_value can store is a Quaternion");
// This is to simplify writing a value into a union.
// Ideally, one would use std::variant (C++17) instead of a union.
memcpy(&param.m_value, &newValue, sizeof(FieldType));
chunk->m_parameters[parameterIndex]->Set(param);
}
else
{
AZ_Warning("EMotionFX", false, "AnimGraphNetSyncComponent does not support synchronizing more than %u parameters", chunk->m_parameters.size());
}
}
}
}
void AnimGraphNetSyncComponent::OnAnimGraphFloatParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
float beforeValue,
float afterValue)
{
AZ_UNUSED(beforeValue);
SetParameterOnServer<AnimParameter::Type::Float>(static_cast<AZ::u8>(parameterIndex), afterValue);
}
void AnimGraphNetSyncComponent::OnAnimGraphBoolParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
bool beforeValue,
bool afterValue)
{
AZ_UNUSED(beforeValue);
SetParameterOnServer<AnimParameter::Type::Bool>(static_cast<AZ::u8>(parameterIndex), afterValue);
}
void AnimGraphNetSyncComponent::OnAnimGraphStringParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const char* beforeValue,
const char* afterValue)
{
AZ_UNUSED(parameterIndex);
AZ_UNUSED(beforeValue);
AZ_UNUSED(afterValue);
AZ_Warning("EMotionFX", false, "AnimGraphNetSync component does not supported synchronizing string parameters, please consider refactoring your anim graph to replace strings with integers or enum values.");
}
void AnimGraphNetSyncComponent::OnAnimGraphVector2ParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Vector2& beforeValue,
const AZ::Vector2& afterValue)
{
AZ_UNUSED(beforeValue);
SetParameterOnServer<AnimParameter::Type::Vector2>(static_cast<AZ::u8>(parameterIndex), afterValue);
}
void AnimGraphNetSyncComponent::OnAnimGraphVector3ParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Vector3& beforeValue,
const AZ::Vector3& afterValue)
{
AZ_UNUSED(beforeValue);
SetParameterOnServer<AnimParameter::Type::Vector3>(static_cast<AZ::u8>(parameterIndex), afterValue);
}
void AnimGraphNetSyncComponent::OnAnimGraphRotationParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Quaternion& beforeValue,
const AZ::Quaternion& afterValue)
{
AZ_UNUSED(beforeValue);
SetParameterOnServer<AnimParameter::Type::Quaternion>(static_cast<AZ::u8>(parameterIndex), afterValue);
}
void AnimGraphNetSyncComponent::OnActiveNodesChanged(const NodeIndexContainer& activeNodes, const GridMate::TimeContext& tc)
{
AZ_UNUSED(tc);
// Client receiving values
if (m_instance)
{
if (const AZStd::shared_ptr<AnimGraphSnapshot> snapshot = m_instance->GetSnapshot())
{
snapshot->SetActiveNodes(activeNodes);
}
}
}
void AnimGraphNetSyncComponent::OnMotionNodesChanged(const MotionNodePlaytimeContainer& motionNodes, const GridMate::TimeContext& tc)
{
AZ_UNUSED(tc);
// Client receiving values
if (m_instance)
{
if (const AZStd::shared_ptr<AnimGraphSnapshot> snapshot = m_instance->GetSnapshot())
{
snapshot->SetMotionNodePlaytimes(motionNodes);
}
}
}
bool AnimGraphNetSyncComponent::IsDifferent(const MotionNodePlaytimeContainer& oldList, const MotionNodePlaytimeContainer& newList) const
{
if (oldList.size() != newList.size())
{
return true;
}
AZStd::size_t i = 0;
for (auto& value : oldList)
{
if (value.first != newList[i].first || value.second != newList[i].second)
{
return true;
}
++i;
}
return false;
}
bool AnimGraphNetSyncComponent::IsDifferent(const NodeIndexContainer& oldList, const NodeIndexContainer& newList) const
{
if (oldList.size() != newList.size())
{
return true;
}
AZStd::size_t i = 0;
for (AZ::u32 value : oldList)
{
if (value != newList[i])
{
return true;
}
++i;
}
return false;
}
void AnimGraphNetSyncComponent::OnTick(float deltaTime, AZ::ScriptTimePoint time)
{
AZ_UNUSED(deltaTime);
AZ_UNUSED(time);
if (!GetChunk())
{
return; // network is not ready yet
}
if (m_instance)
{
if (const AZStd::shared_ptr<AnimGraphSnapshot> snapshot = m_instance->GetSnapshot())
{
if (m_syncActiveNodes)
{
const NodeIndexContainer& activeNodes = snapshot->GetActiveNodes();
const NodeIndexContainer& currentValue = GetChunk()->m_activeNodes.Get();
if (IsDifferent(currentValue, activeNodes))
{
GetChunk()->m_activeNodes.Set(activeNodes); // Server sending the values
}
}
if (m_syncMotionNodes)
{
const MotionNodePlaytimeContainer& playTimes = snapshot->GetMotionNodePlaytimes();
const MotionNodePlaytimeContainer& currentTimes = GetChunk()->m_motionNodes.Get();
if (IsDifferent(currentTimes, playTimes))
{
GetChunk()->m_motionNodes.Set(playTimes); // Server sending the values
}
}
}
}
}
void AnimGraphNetSyncComponent::OnAnimGraphInstanceCreated(EMotionFX::AnimGraphInstance* instance)
{
m_instance = instance;
if (m_instance)
{
const bool isAuthoritative = AzFramework::NetQuery::IsEntityAuthoritative(GetEntityId());
if (!m_instance->GetSnapshot())
{
m_instance->CreateSnapshot(isAuthoritative);
}
}
}
void AnimGraphNetSyncComponent::OnAnimGraphInstanceDestroyed(EMotionFX::AnimGraphInstance*)
{
m_instance = nullptr;
}
AnimGraphNetSyncComponent::Chunk* AnimGraphNetSyncComponent::GetChunk() const
{
return static_cast<Chunk*>(m_chunk.get());
}
GridMate::ReplicaChunkPtr AnimGraphNetSyncComponent::GetNetworkBinding()
{
m_chunk = GridMate::CreateReplicaChunk<Chunk>();
AZ_Assert(m_chunk, "Failed to create a chunk");
if (m_instance)
{
if (!m_instance->GetSnapshot())
{
m_instance->CreateSnapshot(true /* authoritative */);
}
}
return m_chunk;
}
void AnimGraphNetSyncComponent::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk)
{
m_chunk = chunk;
m_chunk->SetHandler(this);
}
void AnimGraphNetSyncComponent::UnbindFromNetwork()
{
AZ_Assert(m_chunk, "There wasn't any chunk present");
if (m_chunk)
{
m_chunk->SetHandler(nullptr);
m_chunk = nullptr;
}
}
}
} // namespace Integration
} // namespace EMotionFXAnimation
@@ -1,153 +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
#include <AzCore/Component/Component.h>
#include <AzCore/Component/TickBus.h>
#include <AzFramework/Network/NetBindable.h>
#include <Integration/AnimGraphComponentBus.h>
#include <Integration/Components/AnimGraphNetSyncTypes.h>
namespace EMotionFX
{
namespace Integration
{
namespace Network
{
/**
* \brief Generic solution for synchronizing parameters of Anim Graph component.
* Synchronization is done over GridMate.
*
* Note that this is not the most optimal synchronization but it does
* work for just about all Anim Graphs.
*
* Disclaimer: string parameters are not supported! Because one should not synchronize
* strings over the network. They ought to be converted to enum/int values beforehand.
*/
class AnimGraphNetSyncComponent
: public AZ::Component
, public AzFramework::NetBindable
, public AnimGraphComponentNotificationBus::Handler
, public AZ::TickBus::Handler
{
public:
AZ_COMPONENT(AnimGraphNetSyncComponent, "{2F9428C1-0F07-4667-B052-40D9BC473AD3}", NetBindable);
static void Reflect(AZ::ReflectContext* context);
// AZ::Component interface implementation
void Activate() override;
void Deactivate() override;
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("EMotionFXAnimGraphNetSyncService", 0x42e6f127));
}
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("EMotionFXAnimGraphNetSyncService", 0x42e6f127));
}
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
{
required.push_back(AZ_CRC("EMotionFXAnimGraphService", 0x9ec3c819));
required.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8));
}
protected:
// NetBindable interface implementation
GridMate::ReplicaChunkPtr GetNetworkBinding() override;
void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) override;
void UnbindFromNetwork() override;
// AnimGraphComponentNotificationBus interface implementation
void OnAnimGraphFloatParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
float beforeValue,
float afterValue) override;
void OnAnimGraphBoolParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
bool beforeValue,
bool afterValue) override;
void OnAnimGraphStringParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const char* beforeValue,
const char* afterValue) override;
void OnAnimGraphVector2ParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Vector2& beforeValue,
const AZ::Vector2& afterValue) override;
void OnAnimGraphVector3ParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Vector3& beforeValue,
const AZ::Vector3& afterValue) override;
void OnAnimGraphRotationParameterChanged(EMotionFX::AnimGraphInstance*,
AZ::u32 parameterIndex,
const AZ::Quaternion& beforeValue,
const AZ::Quaternion& afterValue) override;
// TickBus
void OnTick(float deltaTime, AZ::ScriptTimePoint time) override;
// AnimGraphComponentNotificationBus
void OnAnimGraphInstanceCreated(EMotionFX::AnimGraphInstance* instance) override;
void OnAnimGraphInstanceDestroyed(EMotionFX::AnimGraphInstance* instance) override;
private:
class Chunk;
GridMate::ReplicaChunkPtr m_chunk;
Chunk* GetChunk() const;
// DataSet callback, it's a template to avoid duplicating similar callbacks
template <AZ::u8 Index>
void OnAnimParameterChanged(const AnimParameter& value, const GridMate::TimeContext& tc);
// Helper on a client side
void SetParameterOnClient(const AnimParameter& value, AZ::u8 index);
// Helper on the server side to avoid duplicating very similar callbacks
template <AnimParameter::Type AnimParameterType, typename FieldType>
void SetParameterOnServer(AZ::u8 parameterIndex, const FieldType& newValue);
/**
* \brief Optionally turn on or off replicating parameters of an anim graph on the same entity as this component.
*/
bool m_syncParameters = true;
/**
* \brief Optionally turn on or off replicating active nodes of an anim graph on the same entity as this component.
*/
bool m_syncActiveNodes = false;
/**
* \brief Optionally turn on or off replicating motion playtime nodes of an anim graph on the same entity as this component.
*
* It's off by default because these nodes are very frequently changing and would result in a high network bandwidth use.
*/
bool m_syncMotionNodes = false;
// GridMate DataSet callback on clients
void OnActiveNodesChanged(const NodeIndexContainer& activeNodes, const GridMate::TimeContext& tc);
// GridMate DataSet callback on clients
void OnMotionNodesChanged(const MotionNodePlaytimeContainer& motionNodes, const GridMate::TimeContext& tc);
// Helper comparison method to avoid sending the same data
bool IsDifferent(const NodeIndexContainer& oldList, const NodeIndexContainer& newList) const;
// Helper comparison method to avoid sending the same data
bool IsDifferent(const MotionNodePlaytimeContainer& oldList, const MotionNodePlaytimeContainer& newList) const;
EMotionFX::AnimGraphInstance* m_instance = nullptr;
};
}
} // namespace Integration
} // namespace EMotionFX
@@ -1,285 +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
#include <GridMate/Serialize/Buffer.h>
#include <GridMate/Serialize/MathMarshal.h>
#include <GridMate/Serialize/CompressionMarshal.h>
namespace EMotionFX
{
namespace Integration
{
namespace Network
{
/**
* \brief A general storage for an anim graph parameter.
*/
class AnimParameter
{
public:
/**
* \brief String type is not supported because one should not be syncing strings over the network.
*/
enum class Type : AZ::u8
{
Unsupported,
Float,
Bool,
Vector2,
Vector3,
Quaternion,
};
/**
* \brief A storage for all possible supported types in @AnimGraphNetSyncComponent
*/
union Value
{
Value()
{
q = AZ::Quaternion::CreateZero();
}
float f;
bool b = false;
AZ::Vector2 v2;
AZ::Vector3 v3;
AZ::Quaternion q;
};
AnimParameter() : m_type(Type::Unsupported) {}
Type m_type;
Value m_value;
AnimParameter(const AnimParameter& other)
{
m_type = other.m_type;
CopyValue(other);
}
AnimParameter& operator=(const AnimParameter& other)
{
m_type = other.m_type;
CopyValue(other);
return *this;
}
friend bool operator==(const AnimParameter& lhs, const AnimParameter& rhs)
{
if (lhs.m_type != rhs.m_type)
{
return false;
}
switch (lhs.m_type)
{
case Type::Float:
return lhs.m_value.f == rhs.m_value.f;
case Type::Bool:
return lhs.m_value.b == rhs.m_value.b;
case Type::Vector2:
return lhs.m_value.v2 == rhs.m_value.v2;
case Type::Vector3:
return lhs.m_value.v3 == rhs.m_value.v3;
case Type::Quaternion:
return lhs.m_value.q == rhs.m_value.q;
default:
return true;
}
}
private:
void CopyValue(const AnimParameter& other)
{
switch (m_type)
{
case Type::Float:
m_value.f = other.m_value.f;
break;
case Type::Bool:
m_value.b = other.m_value.b;
break;
case Type::Vector2:
m_value.v2 = other.m_value.v2;
break;
case Type::Vector3:
m_value.v3 = other.m_value.v3;
break;
case Type::Quaternion:
m_value.q = other.m_value.q;
break;
default:
break;
}
}
};
/**
* \brief Custom GridMate throttler. See GridMate:: @BasicThrottle
*/
class AnimParameterThrottler
{
public:
bool WithinThreshold(const AnimParameter& newValue) const
{
return m_baseline == newValue;
}
void UpdateBaseline(const AnimParameter& baseline)
{
m_baseline = baseline;
}
private:
AnimParameter m_baseline;
};
/**
* \brief A custom GridMate marshaler.
* 1 byte is spend on the type. And a variable number of bytes afterwards for the value.
*/
class AnimParameterMarshaler
{
public:
void Marshal(GridMate::WriteBuffer& wb, const AnimParameter& parameter)
{
wb.Write(AZ::u8(parameter.m_type));
switch (parameter.m_type)
{
case AnimParameter::Type::Float:
wb.Write(parameter.m_value.f);
break;
case AnimParameter::Type::Bool:
wb.Write(parameter.m_value.b);
break;
case AnimParameter::Type::Vector2:
wb.Write(parameter.m_value.v2);
break;
case AnimParameter::Type::Vector3:
wb.Write(parameter.m_value.v3);
break;
case AnimParameter::Type::Quaternion:
wb.Write(parameter.m_value.q);
break;
default:
// other types are not supported
break;
}
}
void Unmarshal(AnimParameter& parameter, GridMate::ReadBuffer& rb)
{
AZ::u8 type;
rb.Read(type);
parameter.m_type = static_cast<AnimParameter::Type>(type);
switch (parameter.m_type)
{
case AnimParameter::Type::Float:
rb.Read(parameter.m_value.f);
break;
case AnimParameter::Type::Bool:
rb.Read(parameter.m_value.b);
break;
case AnimParameter::Type::Vector2:
rb.Read(parameter.m_value.v2);
break;
case AnimParameter::Type::Vector3:
rb.Read(parameter.m_value.v3);
break;
case AnimParameter::Type::Quaternion:
rb.Read(parameter.m_value.q);
break;
default:
// other types are not supported
break;
}
}
};
/**
* \brief Custom marshaler for Animation node index that is used by Activate Nodes list
*/
struct NodeIndexContainerMarshaler
{
void Marshal(GridMate::WriteBuffer& wb, const NodeIndexContainer& source) const
{
GridMate::VlqU64Marshaler m64;
GridMate::VlqU32Marshaler m32;
m64.Marshal(wb, source.size()); // 1 byte most of the time (if the size is less than 127)
for (AZ::u32 item : source)
{
m32.Marshal(wb, item); // 1 byte most of the time (if the value is less than 127)
}
}
void Unmarshal(NodeIndexContainer& target, GridMate::ReadBuffer& rb) const
{
target.clear();
GridMate::VlqU64Marshaler m64;
GridMate::VlqU32Marshaler m32;
AZ::u64 arraySize;
m64.Unmarshal(arraySize, rb);
target.resize(arraySize);
for (AZ::u64 i = 0; i < arraySize; ++i)
{
m32.Unmarshal(target[i], rb);
}
}
};
/**
* \brief Custom marshaler for Animation motion node information that is used by motion node playtime list
*/
struct MotionNodePlaytimeContainerMarshaler
{
void Marshal(GridMate::WriteBuffer& wb, const MotionNodePlaytimeContainer& source) const
{
GridMate::VlqU64Marshaler m64;
GridMate::VlqU32Marshaler m32;
m64.Marshal(wb, source.size());
for (const AZStd::pair<AZ::u32, float>& item : source)
{
m32.Marshal(wb, item.first); // average of 1 byte
wb.Write(item.second); // 4 bytes
}
}
void Unmarshal(MotionNodePlaytimeContainer& target, GridMate::ReadBuffer& rb) const
{
target.clear();
GridMate::VlqU64Marshaler m64;
GridMate::VlqU32Marshaler m32;
AZ::u64 arraySize;
m64.Unmarshal(arraySize, rb);
target.resize(arraySize);
for (AZ::u64 i = 0; i < arraySize; ++i)
{
m32.Unmarshal(target[i].first, rb);
rb.Read(target[i].second);
}
}
};
}
} // namespace Integration
} // namespace EMotionFXAnimation
@@ -17,7 +17,6 @@
#include <Integration/Components/ActorComponent.h>
#include <Integration/Components/AnimAudioComponent.h>
#include <Integration/Components/AnimGraphComponent.h>
#include <Integration/Components/AnimGraphNetSyncComponent.h>
#include <Integration/Components/SimpleMotionComponent.h>
#include <Integration/Components/SimpleLODComponent.h>
#include <AzCore/Module/DynamicModuleHandle.h>
@@ -74,8 +73,6 @@ namespace EMotionFX
AnimGraphComponent::CreateDescriptor(),
SimpleMotionComponent::CreateDescriptor(),
SimpleLODComponent::CreateDescriptor(),
Network::AnimGraphNetSyncComponent::CreateDescriptor(),
#if defined(EMOTIONFXANIMATION_EDITOR)
// Pipeline components
@@ -31,9 +31,6 @@ set(FILES
Source/Integration/Components/ActorComponent.cpp
Source/Integration/Components/AnimAudioComponent.h
Source/Integration/Components/AnimAudioComponent.cpp
Source/Integration/Components/AnimGraphNetSyncComponent.h
Source/Integration/Components/AnimGraphNetSyncTypes.h
Source/Integration/Components/AnimGraphNetSyncComponent.cpp
Source/Integration/Components/AnimGraphComponent.h
Source/Integration/Components/AnimGraphComponent.cpp
Source/Integration/Components/SimpleMotionComponent.h
@@ -19,11 +19,9 @@
#include <AzCore/Serialization/SerializeContext.h>
#include <AzCore/Serialization/Utils.h>
#include <AzFramework/Entity/EntityContextBus.h>
#include <AzFramework/Network/NetBindingHandlerBus.h>
#include <ScriptCanvas/Execution/ExecutionBus.h>
#include <ScriptCanvas/Execution/ExecutionContext.h>
#include <ScriptCanvas/Execution/ExecutionState.h>
#include <ScriptCanvas/Variable/GraphVariableNetBindings.h>
#if !defined(_RELEASE) && !defined(PERFORMANCE_BUILD)
#define SCRIPT_CANVAS_RUNTIME_ASSET_CHECK
@@ -163,8 +161,6 @@ namespace ScriptCanvas
->Field("m_variableOverrides", &RuntimeComponent::m_variableOverrides)
;
}
GraphVariableNetBindingTable::Reflect(context);
}
void RuntimeComponent::SetVariableOverrides(const VariableData& overrideData)
@@ -15,8 +15,6 @@
#include <AzCore/Component/Component.h>
#include <AzCore/Component/EntityBus.h>
#include <AzFramework/Network/NetBindable.h>
#include <ScriptCanvas/Asset/RuntimeAsset.h>
#include <ScriptCanvas/Core/Core.h>
#include <ScriptCanvas/Core/ExecutionNotificationsBus.h>
@@ -41,11 +39,10 @@ namespace ScriptCanvas
//! This component should only be used at runtime
class RuntimeComponent
: public AZ::Component
, public AzFramework::NetBindable
, public AZ::EntityBus::Handler
{
public:
AZ_COMPONENT(RuntimeComponent, "{95BFD916-E832-4956-837D-525DE8384282}", NetBindable);
AZ_COMPONENT(RuntimeComponent, "{95BFD916-E832-4956-837D-525DE8384282}", AZ::Component);
static void Reflect(AZ::ReflectContext* context);
@@ -67,8 +64,6 @@ namespace ScriptCanvas
const VariableData& GetVariableOverrides() const;
void SetNetworkBinding(GridMate::ReplicaChunkPtr) {}
void SetVariableOverrides(const VariableData& overrideData);
protected:
@@ -103,8 +98,6 @@ namespace ScriptCanvas
void StopExecution();
void UnbindFromNetwork(void) {}
private:
AZ::Data::Asset<RuntimeAsset> m_runtimeAsset;
ExecutionStatePtr m_executionState;
@@ -1,245 +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 <ScriptCanvas/Variable/GraphVariableMarshal.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <ScriptCanvas/Variable/GraphVariableNetBindings.h>
#include <ScriptCanvas/Core/ModifiableDatumView.h>
#include <AzFramework/Network/EntityIdMarshaler.h>
#include <GridMate/Serialize/MathMarshal.h>
#include <GridMate/Serialize/UtilityMarshal.h>
#include <GridMate/Serialize/UuidMarshal.h>
namespace ScriptCanvas
{
void DatumMarshaler::SetNetBindingTable(GraphVariableNetBindingTable* netBindingTable)
{
m_graphVariableNetBindingTable = netBindingTable;
}
void DatumMarshaler::Marshal(GridMate::WriteBuffer& wb, const Datum* const & property) const
{
if (!property)
{
return;
}
GridMate::Marshaler<Data::eType> typeMarshaler;
const Data::eType& datumType = property->GetType().GetType();
typeMarshaler.Marshal(wb, datumType);
VariableId assetVariableId;
AZStd::unordered_map<VariableId, AZStd::pair<GraphVariable*, int>>& variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap();
for (AZStd::pair<VariableId, AZStd::pair<GraphVariable*, int>>& pair : variableIdMap)
{
AZStd::pair<GraphVariable*, int>& variableIndexPair = pair.second;
if (variableIndexPair.first->GetDatum() == property)
{
assetVariableId = m_graphVariableNetBindingTable->FindAssetVariableIdByRuntimeVariableId(pair.first);
break;
}
}
if (!assetVariableId.IsValid())
{
return;
}
GridMate::Marshaler<AZ::Uuid> uuidMarshaler;
uuidMarshaler.Marshal(wb, assetVariableId.GetDatumId());
AZStd::string uuidString = assetVariableId.m_id.ToString<AZStd::string>();
switch (datumType)
{
case Data::eType::AABB:
MarshalType<Data::AABBType>(wb, property);
break;
case Data::eType::Boolean:
MarshalType<Data::BooleanType>(wb, property);
break;
case Data::eType::Color:
MarshalType<Data::ColorType>(wb, property);
break;
case Data::eType::CRC:
MarshalType<Data::CRCType>(wb, property);
break;
case Data::eType::EntityID:
MarshalType<Data::EntityIDType>(wb, property);
break;
case Data::eType::Matrix3x3:
MarshalType<Data::Matrix3x3Type>(wb, property);
break;
case Data::eType::Matrix4x4:
MarshalType<Data::Matrix4x4Type>(wb, property);
break;
case Data::eType::NamedEntityID:
MarshalType<Data::NamedEntityIDType>(wb, property);
break;
case Data::eType::Number:
MarshalType<Data::NumberType>(wb, property);
break;
case Data::eType::OBB:
MarshalType<Data::OBBType>(wb, property);
break;
case Data::eType::Plane:
MarshalType<Data::PlaneType>(wb, property);
break;
case Data::eType::Quaternion:
MarshalType<Data::QuaternionType>(wb, property);
break;
case Data::eType::String:
MarshalType<Data::StringType>(wb, property);
break;
case Data::eType::Transform:
MarshalType<Data::TransformType>(wb, property);
break;
case Data::eType::Vector2:
MarshalType<Data::Vector2Type>(wb, property);
break;
case Data::eType::Vector3:
MarshalType<Data::Vector3Type>(wb, property);
break;
case Data::eType::Vector4:
MarshalType<Data::Vector4Type>(wb, property);
break;
default:
AZ_Warning("ScriptCanvasNetworking", false, "Marshal unsupported data type");
break;
}
}
bool DatumMarshaler::UnmarshalToPointer(const Datum*& target, GridMate::ReadBuffer& rb)
{
// :SCTODO: for some reason, this UnmarshalToPointer can get called before SetNetworkBinding is called
// (which is where we set m_graphVariableNetBindingTable). So we check for nullptr here just in case.
if (!m_graphVariableNetBindingTable)
{
return false;
}
ScriptCanvas::Data::eType datumType = Data::eType::Invalid;
GridMate::Marshaler<Data::eType> typeMarshaler;
typeMarshaler.Unmarshal(datumType, rb);
AZ::Uuid uuid;
GridMate::Marshaler<AZ::Uuid> uuidMarshaler;
uuidMarshaler.Unmarshal(uuid, rb);
VariableId runtimeVariableId = m_graphVariableNetBindingTable->FindRuntimeVariableIdByAssetVariableId(VariableId(uuid));
if (!runtimeVariableId.IsValid())
{
return false;
}
AZStd::string uuidString = runtimeVariableId.m_id.ToString<AZStd::string>();
AZStd::unordered_map<VariableId, AZStd::pair<GraphVariable*, int>>& m_variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap();
AZStd::pair<GraphVariable*, int>& variableIndexPair = m_variableIdMap[runtimeVariableId];
GraphVariable* graphVariable = variableIndexPair.first;
switch (datumType)
{
case Data::eType::AABB:
return UnmarshalType<Data::AABBType>(target, rb, graphVariable);
case Data::eType::Boolean:
return UnmarshalType<Data::BooleanType>(target, rb, graphVariable);
case Data::eType::Color:
return UnmarshalType<Data::ColorType>(target, rb, graphVariable);
case Data::eType::CRC:
return UnmarshalType<Data::CRCType>(target, rb, graphVariable);
case Data::eType::EntityID:
return UnmarshalType<Data::EntityIDType>(target, rb, graphVariable);
case Data::eType::Matrix3x3:
return UnmarshalType<Data::Matrix3x3Type>(target, rb, graphVariable);
case Data::eType::Matrix4x4:
return UnmarshalType<Data::Matrix4x4Type>(target, rb, graphVariable);
case Data::eType::NamedEntityID:
return UnmarshalType<Data::NamedEntityIDType>(target, rb, graphVariable);
case Data::eType::Number:
return UnmarshalType<Data::NumberType>(target, rb, graphVariable);
case Data::eType::OBB:
return UnmarshalType<Data::OBBType>(target, rb, graphVariable);
case Data::eType::Plane:
return UnmarshalType<Data::PlaneType>(target, rb, graphVariable);
case Data::eType::Quaternion:
return UnmarshalType<Data::QuaternionType>(target, rb, graphVariable);
case Data::eType::String:
return UnmarshalType<Data::StringType>(target, rb, graphVariable);
case Data::eType::Transform:
return UnmarshalType<Data::TransformType>(target, rb, graphVariable);
case Data::eType::Vector2:
return UnmarshalType<Data::Vector2Type>(target, rb, graphVariable);
case Data::eType::Vector3:
return UnmarshalType<Data::Vector3Type>(target, rb, graphVariable);
case Data::eType::Vector4:
return UnmarshalType<Data::Vector4Type>(target, rb, graphVariable);
default:
AZ_Warning("ScriptCanvasNetworking", false, "Unmarshal unsupported data type");
break;
}
return false;
}
void DatumThrottler::SignalDirty()
{
m_isDirty = true;
}
bool DatumThrottler::WithinThreshold(const Datum* newValue) const
{
return (newValue == nullptr || !m_isDirty);
}
void DatumThrottler::UpdateBaseline([[maybe_unused]] const Datum* baseline)
{
m_isDirty = false;
}
}
@@ -1,86 +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
#include <GridMate/Serialize/ContainerMarshal.h>
#include <ScriptCanvas/Core/Datum.h>
#include <ScriptCanvas/Core/ModifiableDatumView.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
namespace ScriptCanvas
{
class GraphVariableNetBindingTable;
class DatumMarshaler
{
public:
void SetNetBindingTable(GraphVariableNetBindingTable* netBindingTable);
void Marshal(GridMate::WriteBuffer& wb, const Datum* const & cont) const;
bool UnmarshalToPointer(const Datum*& target, GridMate::ReadBuffer& rb);
private:
template <typename T>
void MarshalType(GridMate::WriteBuffer& wb, const Datum* const & property) const
{
GridMate::Marshaler<T> marshaler;
const T* value = property->GetAs<T>();
marshaler.Marshal(wb, *value);
}
template <typename T>
bool UnmarshalType(const Datum*& target, GridMate::ReadBuffer& rb, GraphVariable* graphVariable)
{
bool valueChanged = false;
ModifiableDatumView datumView;
if (graphVariable)
{
graphVariable->ConfigureDatumView(datumView);
if (datumView.IsValid())
{
GridMate::Marshaler<T> marshaler;
T value;
marshaler.Unmarshal(value, rb);
datumView.SetAs(value);
target = graphVariable->GetDatum();
valueChanged = true;
}
}
return valueChanged;
}
private:
//! The network binding table is needed to determine which Datum to update
//! when unmarshaling data.
// :SCTODO: synced Datums should be tracked via ID
//! and that ID should be used to lookup Datums (right now we can assume
//! which Datum should be updated, since only one Datum is supported).
GraphVariableNetBindingTable* m_graphVariableNetBindingTable = nullptr;
};
//! Simple throttler that simple operates via dirty flag.
class DatumThrottler
{
public:
DatumThrottler() = default;
void SignalDirty();
bool WithinThreshold(const Datum* newValue) const;
void UpdateBaseline(const Datum* baseline);
private:
bool m_isDirty = false;
};
}
@@ -1,181 +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 <ScriptCanvas/Execution/RuntimeBus.h>
#include <ScriptCanvas/Variable/GraphVariable.h>
#include <ScriptCanvas/Variable/GraphVariableNetBindings.h>
#include <ScriptCanvas/Core/Datum.h>
#include <GridMate/Replica/DataSet.h>
#include <GridMate/Replica/ReplicaFunctions.h>
#include <AzFramework/Network/NetworkContext.h>
namespace ScriptCanvas
{
const char* DatumDataSet::GetDataSetName()
{
static size_t s_chunkIndex = 0;
static const char* s_nameArray[] = {
"DataSet1","DataSet2","DataSet3","DataSet4","DataSet5",
"DataSet6","DataSet7","DataSet8","DataSet9","DataSet10",
"DataSet11","DataSet12","DataSet13","DataSet14","DataSet15",
"DataSet16","DataSet17","DataSet18","DataSet19","DataSet20",
"DataSet21","DataSet22","DataSet23","DataSet24","DataSet25",
"DataSet26","DataSet27","DataSet28","DataSet29","DataSet30",
"DataSet31","DataSet32"
};
if (s_chunkIndex > AZ_ARRAY_SIZE(s_nameArray) && AZ_ARRAY_SIZE(s_nameArray) >= 0)
{
s_chunkIndex = s_chunkIndex % AZ_ARRAY_SIZE(s_nameArray);
}
return s_nameArray[s_chunkIndex++];
}
DatumDataSet::DatumDataSet()
: DatumDataSetType(DatumDataSet::GetDataSetName())
{
}
//////////////////////////
// GraphVariableReplicaChunk
//////////////////////////
const char* GraphVariableReplicaChunk::GetChunkName()
{
return "GraphVariableReplicaChunk";
}
bool GraphVariableReplicaChunk::IsReplicaMigratable()
{
return true;
}
//////////////////////////
// GraphVariableNetBindingTable
//////////////////////////
void GraphVariableNetBindingTable::Reflect([[maybe_unused]] AZ::ReflectContext* reflect)
{
GridMate::ReplicaChunkDescriptorTable& descriptorTable = GridMate::ReplicaChunkDescriptorTable::Get();
AZ::Crc32 hash = GridMate::ReplicaChunkClassId(GraphVariableReplicaChunk::GetChunkName());
if (!descriptorTable.FindReplicaChunkDescriptor(hash))
{
descriptorTable.RegisterChunkType<GraphVariableReplicaChunk>();
}
}
GridMate::ReplicaChunkPtr GraphVariableNetBindingTable::GetNetworkBinding()
{
if (!m_replicaChunk)
{
m_replicaChunk = GridMate::CreateReplicaChunk<GraphVariableReplicaChunk>();
m_replicaChunk->SetHandler(this);
SetGraphNetBindingTable();
}
return m_replicaChunk;
}
void GraphVariableNetBindingTable::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk)
{
m_replicaChunk = chunk;
m_replicaChunk->SetHandler(this);
SetGraphNetBindingTable();
}
void GraphVariableNetBindingTable::UnbindFromNetwork()
{
if (m_replicaChunk)
{
m_replicaChunk->SetHandler(nullptr);
m_replicaChunk = nullptr;
}
}
void GraphVariableNetBindingTable::OnPropertyUpdate([[maybe_unused]] const Datum* const & scriptProperty, [[maybe_unused]] const GridMate::TimeContext& tc)
{
}
void GraphVariableNetBindingTable::AddDatum(GraphVariable* variable)
{
size_t index = m_variableIdMap.size();
m_variableIdMap[variable->GetVariableId()] = AZStd::make_pair(variable, static_cast<int>(index));
}
void GraphVariableNetBindingTable::OnDatumChanged(GraphVariable& variable)
{
if (m_replicaChunk && m_replicaChunk->IsMaster())
{
GraphVariableReplicaChunk* graphVarChunk = static_cast<GraphVariableReplicaChunk*>(m_replicaChunk.get());
auto iter = m_variableIdMap.find(variable.GetVariableId());
if (iter == m_variableIdMap.end())
{
AZ_TracePrintf("ScriptCanvasNetworking", "GraphVariableNetBindingTable::OnDatumChanged: variable not found");
return;
}
const AZStd::pair<GraphVariable*, int>& pair = iter->second;
DatumDataSet& datumDataSet = graphVarChunk->m_properties[pair.second];
datumDataSet.GetThrottler().SignalDirty();
datumDataSet.Set(variable.GetDatum());
}
}
void GraphVariableNetBindingTable::SetVariableMappings(const AZStd::unordered_map<VariableId, VariableId>& assetToRuntimeVariableMap, const AZStd::unordered_map<VariableId, VariableId>& runtimeToAssetVariableMap)
{
m_assetToRuntimeVariableMap = assetToRuntimeVariableMap;
m_runtimeToAssetVariableMap = runtimeToAssetVariableMap;
}
VariableId GraphVariableNetBindingTable::FindAssetVariableIdByRuntimeVariableId(VariableId runtimeVariableId)
{
auto iter = m_runtimeToAssetVariableMap.find(runtimeVariableId);
if (iter != m_runtimeToAssetVariableMap.end())
{
return iter->second;
}
return VariableId();
}
VariableId GraphVariableNetBindingTable::FindRuntimeVariableIdByAssetVariableId(VariableId assetVariableId)
{
auto iter = m_assetToRuntimeVariableMap.find(assetVariableId);
if (iter != m_assetToRuntimeVariableMap.end())
{
return iter->second;
}
return VariableId();
}
AZStd::unordered_map<VariableId, AZStd::pair<GraphVariable*, int>>& GraphVariableNetBindingTable::GetVariableIdMap()
{
return m_variableIdMap;
}
void GraphVariableNetBindingTable::SetGraphNetBindingTable()
{
GraphVariableReplicaChunk* graphVariableChunk = static_cast<GraphVariableReplicaChunk*>(m_replicaChunk.get());
for (DatumDataSet& dataSet : graphVariableChunk->m_properties)
{
dataSet.GetMarshaler().SetNetBindingTable(this);
}
}
}
@@ -1,101 +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
#include <AzCore/RTTI/ReflectContext.h>
#include <GridMate/Replica/DataSet.h>
#include <GridMate/Replica/ReplicaChunkInterface.h>
#include <GridMate/Replica/ReplicaCommon.h>
#include <ScriptCanvas/Variable/GraphVariableMarshal.h>
namespace ScriptCanvas
{
class GraphVariable;
class GraphVariableReplicaChunk;
//! Core functionality for managing replicated Datums in a script canvas and the
//! corresponding GridMate callbacks and data structs (DataSets).
class GraphVariableNetBindingTable
: public GridMate::ReplicaChunkInterface
{
public:
AZ_CLASS_ALLOCATOR(GraphVariableNetBindingTable, AZ::SystemAllocator, 0);
static void Reflect(AZ::ReflectContext* reflect);
GraphVariableNetBindingTable() = default;
~GraphVariableNetBindingTable() = default;
GridMate::ReplicaChunkPtr GetNetworkBinding();
void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk);
void UnbindFromNetwork();
//! Gets called when the given Datum object is updated with a new value
//! that was received over the network.
void OnPropertyUpdate(const Datum* const & scriptProperty, const GridMate::TimeContext& tc);
//! Adds the given Datum to the list of "synced datums" for this instance.
void AddDatum(GraphVariable* variable);
//! Called when local data changes for a Datum whose values should be replicated
//! over the network.
void OnDatumChanged(GraphVariable& variable);
void SetVariableMappings(const AZStd::unordered_map<VariableId, VariableId>& assetToRuntimeVariableMap, const AZStd::unordered_map<VariableId, VariableId>& runtimeToAssetVariableMap);
VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeVariableId);
VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetVariableId);
AZStd::unordered_map<VariableId, AZStd::pair<GraphVariable*, int>>& GetVariableIdMap();
private:
void SetGraphNetBindingTable();
private:
AZStd::unordered_map<VariableId, VariableId> m_assetToRuntimeVariableMap;
AZStd::unordered_map<VariableId, VariableId> m_runtimeToAssetVariableMap;
//! Replica chunk used for GridMate networking binding. See GraphVariableReplicaChunk.
GridMate::ReplicaChunkPtr m_replicaChunk;
//! Contains pointers to all replicated variables contained within the runtime component
//! of the canvas this net binding is associated with.
AZStd::unordered_map<VariableId, AZStd::pair<GraphVariable*, int>> m_variableIdMap;
};
typedef GridMate::DataSet<const Datum*, DatumMarshaler, DatumThrottler>::BindInterface<GraphVariableNetBindingTable, &GraphVariableNetBindingTable::OnPropertyUpdate> DatumDataSetType;
class DatumDataSet
: public DatumDataSetType
{
public:
DatumDataSet();
~DatumDataSet() = default;
private:
const char* GetDataSetName();
};
class GraphVariableReplicaChunk
: public GridMate::ReplicaChunkBase
{
public:
AZ_CLASS_ALLOCATOR(GraphVariableReplicaChunk, AZ::SystemAllocator, 0);
static const char* GetChunkName();
GraphVariableReplicaChunk() = default;
~GraphVariableReplicaChunk() = default;
bool IsReplicaMigratable() override;
DatumDataSet m_properties[GM_MAX_DATASETS_IN_CHUNK];
};
}
@@ -597,10 +597,6 @@ set(FILES
Include/ScriptCanvas/Variable/GraphVariable.cpp
Include/ScriptCanvas/Variable/GraphVariableManagerComponent.h
Include/ScriptCanvas/Variable/GraphVariableManagerComponent.cpp
Include/ScriptCanvas/Variable/GraphVariableNetBindings.h
Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp
Include/ScriptCanvas/Variable/GraphVariableMarshal.h
Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp
Include/ScriptCanvas/Variable/VariableCore.h
Include/ScriptCanvas/Variable/VariableCore.cpp
Include/ScriptCanvas/Variable/VariableData.h