diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp index ba313812ce..dc6ae684cf 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.cpp +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.cpp @@ -52,8 +52,6 @@ #include #include #include -#include -#include #include #include #include @@ -66,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -197,7 +194,6 @@ namespace AzFramework ApplicationRequests::Bus::Handler::BusConnect(); AZ::UserSettingsFileLocatorBus::Handler::BusConnect(); - NetSystemRequestBus::Handler::BusConnect(); } Application::~Application() @@ -207,7 +203,6 @@ namespace AzFramework Stop(); } - NetSystemRequestBus::Handler::BusDisconnect(); AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect(); ApplicationRequests::Bus::Handler::BusDisconnect(); @@ -285,13 +280,6 @@ namespace AzFramework m_pimpl.reset(); - /* The following line of code is a temporary fix. - * GridMate's ReplicaChunkDescriptor is stored in a global environment variable 'm_globalDescriptorTable' - * which does not get cleared when Application shuts down. We need to un-reflect here to clear ReplicaChunkDescriptor - * so that ReplicaChunkDescriptor::m_vdt doesn't get flooded when we repeatedly instantiate Application in unit tests. - */ - AZ::ReflectionEnvironment::GetReflectionManager()->RemoveReflectContext(); - // Free any memory owned by the command line container. m_commandLine = CommandLine(); @@ -320,8 +308,6 @@ namespace AzFramework azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), azrtti_typeid(), @@ -457,9 +443,6 @@ namespace AzFramework void Application::CreateReflectionManager() { ComponentApplication::CreateReflectionManager(); - - // Setup NetworkContext - AZ::ReflectionEnvironment::GetReflectionManager()->AddReflectContext(); } //////////////////////////////////////////////////////////////////////////// @@ -479,19 +462,6 @@ namespace AzFramework return uuid; } - //////////////////////////////////////////////////////////////////////////// - NetworkContext* Application::GetNetworkContext() - { - NetworkContext* result = nullptr; - - if (auto reflectionManager = AZ::ReflectionEnvironment::GetReflectionManager()) - { - result = reflectionManager->GetReflectContext(); - } - - return result; - } - void Application::ResolveEnginePath(AZStd::string& engineRelativePath) const { AZ::IO::FixedMaxPath fullPath = m_engineRoot / engineRelativePath; diff --git a/Code/Framework/AzFramework/AzFramework/Application/Application.h b/Code/Framework/AzFramework/AzFramework/Application/Application.h index 4d7e45a423..6b1283be34 100644 --- a/Code/Framework/AzFramework/AzFramework/Application/Application.h +++ b/Code/Framework/AzFramework/AzFramework/Application/Application.h @@ -21,7 +21,6 @@ #include #include -#include #include #include @@ -49,7 +48,6 @@ namespace AzFramework : public AZ::ComponentApplication , public AZ::UserSettingsFileLocatorBus::Handler , public ApplicationRequests::Bus::Handler - , public NetSystemRequestBus::Handler { public: // Base class for platform specific implementations of the application. @@ -138,11 +136,6 @@ namespace AzFramework // Convenience function that should be called instead of the standard exit() function to ensure platform requirements are met. static void Exit(int errorCode) { ApplicationRequests::Bus::Broadcast(&ApplicationRequests::TerminateOnError, errorCode); } - ////////////////////////////////////////////////////////////////////////// - //! NetSystemEventBus::Handler - ////////////////////////////////////////////////////////////////////////// - NetworkContext* GetNetworkContext() override; - protected: /** diff --git a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp index 644a7d099d..d1e4b4977a 100644 --- a/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp +++ b/Code/Framework/AzFramework/AzFramework/AzFrameworkModule.cpp @@ -22,8 +22,6 @@ #include #include #include -#include -#include #include #include #include @@ -42,8 +40,6 @@ namespace AzFramework AzFramework::AssetCatalogComponent::CreateDescriptor(), AzFramework::CustomAssetTypeComponent::CreateDescriptor(), AzFramework::FileTag::ExcludeFileComponent::CreateDescriptor(), - AzFramework::NetBindingComponent::CreateDescriptor(), - AzFramework::NetBindingSystemComponent::CreateDescriptor(), AzFramework::TransformComponent::CreateDescriptor(), AzFramework::NonUniformScaleComponent::CreateDescriptor(), AzFramework::GameEntityContextComponent::CreateDescriptor(), diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp index 5605fe567c..3c05887a89 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.cpp @@ -878,15 +878,15 @@ namespace AzFramework AZ::SerializeContext* serializeContext = azrtti_cast(reflection); if (serializeContext) { - serializeContext->Class() + serializeContext->ClassDeprecate("NetBindable", "{80206665-D429-4703-B42E-94434F82F381}"); + + serializeContext->Class() ->Version(4, &TransformComponentVersionConverter) ->Field("Parent", &TransformComponent::m_parentId) ->Field("Transform", &TransformComponent::m_worldTM) ->Field("LocalTransform", &TransformComponent::m_localTM) ->Field("ParentActivationTransformMode", &TransformComponent::m_parentActivationTransformMode) ->Field("IsStatic", &TransformComponent::m_isStatic) - ->Field("InterpolatePosition", &TransformComponent::m_interpolatePosition) - ->Field("InterpolateRotation", &TransformComponent::m_interpolateRotation) ; } diff --git a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h index abea0bd4dd..0dd53d84ed 100644 --- a/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Components/TransformComponent.h @@ -17,7 +17,6 @@ #include #include #include -#include namespace AzToolsFramework { @@ -41,10 +40,9 @@ namespace AzFramework , public AZ::TransformBus::Handler , public AZ::TransformNotificationBus::Handler , private AZ::TransformHierarchyInformationBus::Handler - , public NetBindable { public: - AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, NetBindable, AZ::TransformInterface); + AZ_COMPONENT(TransformComponent, AZ::TransformComponentTypeId, AZ::TransformInterface); friend class AzToolsFramework::Components::TransformComponent; @@ -218,11 +216,5 @@ namespace AzFramework bool m_parentActive = false; ///< Keeps track of the state of the parent entity. bool m_onNewParentKeepWorldTM = true; ///< If set, recompute localTM instead of worldTM when parent becomes active. bool m_isStatic = false; ///< If true, the transform is static and doesn't move while entity is active. - - //! @deprecated - //! @{ - AZ::InterpolationMode m_interpolatePosition = AZ::InterpolationMode::NoInterpolation; - AZ::InterpolationMode m_interpolateRotation = AZ::InterpolationMode::NoInterpolation; - //! @} }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h deleted file mode 100644 index 3e69454f59..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/DynamicSerializableFieldMarshaler.h +++ /dev/null @@ -1,146 +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 -#ifndef AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H -#define AZFRAMEWORK_NETWORK_DYNAMICSERIALIZABLEFIELDMARSHALER_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace GridMate -{ - /** - * Marshaler for DynamicSerializableField, contains a template param for allocating the memory buffer that it's going to use to write to. - */ - template - class DynamicSerializableFieldMarshaler - { - public: - DynamicSerializableFieldMarshaler() - : m_serializeContext(nullptr) - { - EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - } - - // Mainly here for unit test purposes. - DynamicSerializableFieldMarshaler(AZ::SerializeContext* context) - : m_serializeContext(context) - { - } - - AZ_FORCE_INLINE void Marshal(WriteBuffer& wb, const AZ::DynamicSerializableField& value) const - { - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Marshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - Marshaler uuidMarshaler; - - AZStd::vector memoryBuffer(BufferSize); - - // Start buffer in write mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - AZ::u32 bufferSize = 0; - - if (m_serializeContext->FindClassData(value.m_typeId)) - { - if (AZ::Utils::SaveObjectToStream(memoryStream, AZ::DataStream::StreamType::ST_BINARY, value.m_data, value.m_typeId, m_serializeContext)) - { - bufferSize = static_cast(memoryStream.GetCurPos()); - } - } - else - { - AZ_Error("DynamicSerializableFieldMarshaler", !value.IsValid(), "Could not save object to stream because type Id %s is not registered with the serializer.\n", value.m_typeId.ToString().c_str()); - } - - sizeMarshaler.Marshal(wb, bufferSize); - uuidMarshaler.Marshal(wb, value.m_typeId); - wb.WriteRaw(memoryBuffer.data(), bufferSize); - } - } - - AZ_FORCE_INLINE void Unmarshal(AZ::DynamicSerializableField& value, ReadBuffer& rb) const - { - value.DestroyData(m_serializeContext); - - AZ_Error("DynamicSerializableFieldMarshaler", m_serializeContext, "Unknown SerializationContext. Aborting Unmarshal attempt.\n"); - if (m_serializeContext) - { - Marshaler sizeMarshaler; - AZ::u32 marshaledBufferSize = 0; - sizeMarshaler.Unmarshal(marshaledBufferSize, rb); - - AZ_Assert(marshaledBufferSize <= BufferSize,"Trying to deserialize too much data for the allocated buffer size\n"); - - // Marshal out the TypeId so I can use it on the receiving end. - Marshaler uuidMarshaler; - uuidMarshaler.Unmarshal(value.m_typeId, rb); - - if (marshaledBufferSize > 0) - { - // See if there's some nice way to use this. - // - Can't make this a member variable, since both these methods are const. - AZStd::vector memoryBuffer(marshaledBufferSize + 1); - - if (rb.ReadRaw(memoryBuffer.data(), marshaledBufferSize)) - { - // Start buffer in read mode. - AZ::IO::ByteContainerStream memoryStream(&memoryBuffer); - - // we'll use a strict filter here, one that doesn't allow deserialization to automatically start loading assets, nor tolerates errors. - // this is becuase this is coming from a network interface and should always be error-free. - AZ::ObjectStream::FilterDescriptor filterToUse(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_STRICT); - value.m_data = AZ::Utils::LoadObjectFromStream(memoryStream, m_serializeContext, &value.m_typeId, filterToUse); - } - } - } - } - - private: - AZ::SerializeContext* m_serializeContext; - }; - - /** - * Specialized marshaler for AZ::DynamicSerializableField - * Mainly here to hook into the DataSet Marshaler auto detection logic, and provide a default buffer size for the actual marshaler - */ - template<> - class Marshaler - : public DynamicSerializableFieldMarshaler<1024> - { - public: - - Marshaler() - { - } - - // Mainly here for unit test purposes. - Marshaler(AZ::SerializeContext* context) - : DynamicSerializableFieldMarshaler(context) - { - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h b/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h deleted file mode 100644 index 0116020cc0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/EntityIdMarshaler.h +++ /dev/null @@ -1,76 +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 -#ifndef AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H -#define AZFRAMEWORK_NETWORK_ENTITYIDMARSHALER_H - -#include -#include - -#include -#include - -namespace GridMate -{ - template<> - class Marshaler - { - public: - AZ_TYPE_INFO_LEGACY( Marshaler, "{23F4722F-D104-4E30-9342-43F4DDD1894D}", AZ::EntityId ); - - void Marshal(GridMate::WriteBuffer& wb, const AZ::EntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb,static_cast(source)); - } - - void Unmarshal(AZ::EntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id,rb); - - target = AZ::EntityId(id); - } - }; - - template<> - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const AZ::NamedEntityId& source) const - { - Marshaler idMarshaler; - idMarshaler.Marshal(wb, static_cast(source)); - - Marshaler stringMarshaler; - stringMarshaler.Marshal(wb, source.GetName()); - } - - void Unmarshal(AZ::NamedEntityId& target, GridMate::ReadBuffer& rb) const - { - AZ::u64 id = 0; - - Marshaler idMarshaler; - idMarshaler.Unmarshal(id, rb); - - AZStd::string name; - Marshaler stringMarshaler; - stringMarshaler.Unmarshal(name, rb); - - target = AZ::NamedEntityId(AZ::EntityId(id), name); - } - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp deleted file mode 100644 index 6aa32158f1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.cpp +++ /dev/null @@ -1,187 +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 - -#include -#include -#include - -#include -#include -#include -#include - -using namespace GridMate; - -namespace AzFramework -{ - void InterestManagerComponent::Reflect(AZ::ReflectContext* context) - { - if (context) - { - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "InterestManagerComponent", "Interest manager instance") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)); - } - } - - // We need to register the chunk types for each handler here at reflect time - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ProximityInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(BitmaskInterestChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - void InterestManagerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - void InterestManagerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("InterestManager", 0x79993873)); - } - - - - InterestManagerComponent::InterestManagerComponent() - : m_im(nullptr) - , m_bitmaskHandler(nullptr) - , m_proximityHandler(nullptr) - , m_session(nullptr) - { - - } - - void InterestManagerComponent::Activate() - { - InterestManagerRequestsBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - } - - void InterestManagerComponent::Deactivate() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - InterestManagerRequestsBus::Handler::BusDisconnect(); - - ShutdownInterestManager(); - } - - void InterestManagerComponent::OnSystemTick() - { - if (m_im && m_im->IsReady()) - { - m_im->Update(); - } - } - - InterestManager* InterestManagerComponent::GetInterestManager() - { - return m_im.get(); - } - - BitmaskInterestHandler* InterestManagerComponent::GetBitmaskInterest() - { - return m_bitmaskHandler.get(); - } - - ProximityInterestHandler* InterestManagerComponent::GetProximityInterest() - { - return m_proximityHandler.get(); - } - - void InterestManagerComponent::OnNetworkSessionActivated(GridSession* session) - { - AZ_Assert(m_session == nullptr, "Already bound to the session"); - - AZ_TracePrintf("AzFramework", "Interest manager hooked up to the session '%s'\n", session->GetId().c_str()); - - m_session = session; - m_session->GetReplicaMgr()->SetAutoBroadcast(false); - - InitInterestManager(); - } - - void InterestManagerComponent::OnNetworkSessionDeactivated(GridSession* session) - { - if (m_session && m_session == session) - { - AZ_TracePrintf("AzFramework", "Interest manager disconnected from the session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - - if (m_session->GetReplicaMgr()) - { - m_session->GetReplicaMgr()->SetAutoBroadcast(true); - } - - m_session = nullptr; - ShutdownInterestManager(); - } - else - { - AZ_Warning("AzFramework", false, "Interest manager was never active for session '%s'\n", session ? session->GetId().c_str() : "nullptr"); - } - } - - void InterestManagerComponent::InitInterestManager() - { - AZ_Assert(m_im == nullptr, "Already initialized interest manager"); - m_im = AZStd::make_unique(); - - InterestManagerDesc desc; - desc.m_rm = m_session->GetReplicaMgr(); - m_im->Init(desc); - - m_bitmaskHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_bitmaskHandler.get()); - - m_proximityHandler = AZStd::make_unique(); - m_im->RegisterHandler(m_proximityHandler.get()); - - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerActivate, m_im.get()); - } - - void InterestManagerComponent::ShutdownInterestManager() - { - if (m_im) - { - InterestManagerEventsBus::Broadcast( - &InterestManagerEventsBus::Events::OnInterestManagerDeactivate, m_im.get()); - - m_im->UnregisterHandler(m_bitmaskHandler.get()); - m_im->UnregisterHandler(m_proximityHandler.get()); - - m_bitmaskHandler = nullptr; - m_proximityHandler = nullptr; - m_im = nullptr; - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h b/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h deleted file mode 100644 index de45c78d43..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/InterestManagerComponent.h +++ /dev/null @@ -1,120 +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. -* -*/ -#ifndef AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H -#define AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H - - -#include -#include -#include - -#include - -#include - -namespace GridMate -{ - class InterestManager; - class GridSession; - class BitmaskInterestHandler; - class ProximityInterestHandler; -} - -namespace AzFramework -{ - class InterestManagerSystemRequests - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerSystemRequests() {} - - // Returns interest manager instance - virtual GridMate::InterestManager* GetInterestManager() = 0; - - // Returns interest manager instance - virtual GridMate::BitmaskInterestHandler* GetBitmaskInterest() = 0; - - // Returns interest manager instance - virtual GridMate::ProximityInterestHandler* GetProximityInterest() = 0; - }; - - // Interface Bus - using InterestManagerRequestsBus = AZ::EBus; - - class InterestManagerEvents - : public AZ::EBusTraits - { - public: - virtual ~InterestManagerEvents() {} - - // Called when interest manager is initialized and ready to use - virtual void OnInterestManagerActivate(GridMate::InterestManager* im) { (void)im; } - - // Called when interest manager is deactivated - virtual void OnInterestManagerDeactivate(GridMate::InterestManager* im) { (void)im; } - }; - - // Interface Bus - using InterestManagerEventsBus = AZ::EBus; - - /** - * Interest manager component. - * When component is activated replicas will go through interest filtering before being sent to other peers - */ - class InterestManagerComponent - : public AZ::Component - , public AZ::SystemTickBus::Handler - , public InterestManagerRequestsBus::Handler - , public NetBindingSystemEventsBus::Handler - { - public: - AZ_COMPONENT(InterestManagerComponent, "{55371FA7-2942-4A3C-A3EA-27FF2C7DB6C5}"); - - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - - InterestManagerComponent(); - - void Activate() override; - void Deactivate() override; - - protected: - - // AZ::SystemTickBus::Listener interface implementation - void OnSystemTick() override; - - // InterestManagerSystemRequests implementation - GridMate::InterestManager* GetInterestManager() override; - GridMate::BitmaskInterestHandler* GetBitmaskInterest() override; - GridMate::ProximityInterestHandler* GetProximityInterest() override; - - // SessionEventBus - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - - void InitInterestManager(); - void ShutdownInterestManager(); - - // Interest handlers - AZStd::unique_ptr m_im; - AZStd::unique_ptr m_bitmaskHandler; - AZStd::unique_ptr m_proximityHandler; - - GridMate::GridSession* m_session; ///< currently bound session - - private: - InterestManagerComponent(const InterestManagerComponent&) = delete; //Cannot use default due to unique_ptr. - }; -} // namesapce AzFramework - -#endif // AZFRAMEWORK_NET_INTERESTMANAGER_COMPONENT_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp deleted file mode 100644 index eb0e6efa47..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.cpp +++ /dev/null @@ -1,111 +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 -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - //////////////// - // NetBindable - //////////////// - - NetBindable::NetBindable() - : m_isSyncEnabled(true) - { - } - - NetBindable::~NetBindable() - { - if (m_chunk) - { - // NetBindable is a base class for handlers for replica chunks, so we have to clear the handler since this object is about to go away - m_chunk->SetHandler(nullptr); - m_chunk = nullptr; - } - } - - GridMate::ReplicaChunkPtr NetBindable::GetNetworkBinding() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - m_chunk = netContext->CreateReplicaChunk(azrtti_typeid(this)); - netContext->Bind(this, m_chunk, NetworkContextBindMode::Authoritative); - return m_chunk; - } - - return nullptr; - } - - void NetBindable::SetNetworkBinding (GridMate::ReplicaChunkPtr chunk) - { - m_chunk = chunk; - - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, m_chunk, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::UnbindFromNetwork() - { - if (m_chunk) - { - // NetworkContext-reflected chunks need access to the handler when they are being destroyed, so we won't null handler in here - m_chunk = nullptr; - } - } - - void NetBindable::NetInit() - { - NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_Assert(netContext, "Cannot bind objects to the network with no NetworkContext"); - if (netContext) - { - netContext->Bind(this, nullptr, NetworkContextBindMode::NonAuthoritative); - } - } - - void NetBindable::Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ->Field("m_isSyncEnabled", &NetBindable::m_isSyncEnabled); - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Bindable", "Network-bindable components are synchronized over the network.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)) - ->DataElement(AZ::Edit::UIHandlers::Default, &NetBindable::m_isSyncEnabled, "Bind To network", "Enable binding to the network."); - } - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h deleted file mode 100644 index 39a05c4fc1..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindable.h +++ /dev/null @@ -1,799 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDABLE_H -#define AZFRAMEWORK_NET_BINDABLE_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -/* - * Including common GridMate marshallers. - * Otherwise, users of NetBindable/NetworkContext have to find and include them themselves. - */ -#include -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - class ReflectContext; - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer; - } -} - -namespace AzFramework -{ - using GridMate::DataSetBase; - using GridMate::DataSet; - using GridMate::Marshaler; - using GridMate::BasicThrottle; - using GridMate::RpcBase; - using GridMate::TimeContext; - using GridMate::RpcContext; - using GridMate::RpcDefaultTraits; - - enum class NetworkContextBindMode - { - Authoritative, - NonAuthoritative - }; - - /** - * Components that want to be synchronized over the network should implement NetBindable. - * The NetBindable interface is obtained via AZ_RTTI so components need to make sure to - * declare NetBindable as a base class in their AZ_RTTI declaration (or AZ_COMPONENT declaration), - * as well as to declare both AZ::Component and NetBindable as base classes in the reflection. - * - * For example, here is how to mark a component for network replication in its class declaration: - * - * class TestFieldComponent - * : public AZ::Component - * , public AzFramework::NetBindable - * { - * public: - * AZ_COMPONENT(TestFieldComponent, "{DD02A926-F6B3-4820-9587-62EED9EEBB3F}", NetBindable); - * - * static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - * { - * required.push_back(AZ_CRC("ReplicaChunkService")); - * } - * - * Note, you should declare a dependency on NetBindingComponent as it is done above with "ReplicaChunkService." - * NetBindingComponent is required for an entity to be considered for network replication and replicate your NetBindable-components. - */ - class NetBindable - : public GridMate::ReplicaChunkInterface - { - public: - AZ_RTTI(NetBindable, "{80206665-D429-4703-B42E-94434F82F381}"); - - NetBindable(); - virtual ~NetBindable(); - - void NetInit(); - - //! Called during network binding on the master. The default implementation will use the - //! NetworkContext to create a chunk. User implementations should create and return a new binding. - virtual GridMate::ReplicaChunkPtr GetNetworkBinding(); - - //! Called during network binding on proxies. - virtual void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - - //! Called when network is unbound. Implementations should release their references to the binding, if they held a reference. - virtual void UnbindFromNetwork(); - - static void Reflect(AZ::ReflectContext* reflection); - - template , typename ThrottlerType = BasicThrottle > - class Field; - - template , typename ThrottlerType = BasicThrottle > - class BoundField; - - template - class Rpc; - - inline bool IsSyncEnabled() const { return m_isSyncEnabled; } - //! Can be used to disabled net sync on a per component basis - inline void SetSyncEnabled(bool enabled) { m_isSyncEnabled = enabled; } - protected: - bool m_isSyncEnabled; - GridMate::ReplicaChunkPtr m_chunk = nullptr; - }; - - class NetBindableFieldBase - { - public: - virtual ~NetBindableFieldBase() = default; - virtual void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) = 0; - }; - - /** - * \brief NetBindable provides a simplified network interface to mark a member variable inside AZ::Component - * as a network field that will be replicated by GridMate. - * - * \tparam DataType data type of the field, can be either a common C++ type or a custom type - * \tparam MarshalerType optional, marshaler type that provides custom marshal and unmarshal logic, i.e. how to write @DataType to the network and back, see @GridMate::Marshaler - * \tparam ThrottlerType optional, throttler provides the ability to detect if a value is to be considered changed significantly enough for GridMate to replicate its state, see @GridMate::BasicThrottle - * - * Example: - * - * class TestFieldComponent : public AZ::Component , public AzFramework::NetBindable - * { - * public: - * Field m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext: - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - * - * Then you can simply write to it as it was an integer: - * - * m_testInt = 3; - * // or - * m_testInt = *m_testInt + 1; - */ - template - class NetBindable::Field - : public NetBindableFieldBase - { - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - using DataSetType = DataSet; - using ValueType = DataType; - - explicit Field(const DataType& value = DataType()) - : m_dataSet(nullptr) - , m_value(value) - {} - ~Field() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - Field (const Field& other) = delete; - Field (Field&& other) = delete; - Field& operator= (const Field& other) = delete; - Field& operator= (Field&& other) = delete; - - const DataType& Get() const - { - return m_dataSet ? m_dataSet->Get() : m_value; - } - - virtual operator const DataType&() const - { - return Get(); - } - - virtual const DataType& operator*() const - { - return Get(); - } - - virtual Field& operator=(const DataType& val) - { - if (m_dataSet) - { - m_dataSet->Set(val); - } - else - { - m_value = val; - } - return *this; - } - - virtual Field& operator=(const DataType&& val) - { - if (m_dataSet) - { - m_dataSet->Set(AZStd::forward(val)); - } - else - { - m_value = AZStd::move(val); - } - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - - protected: - template - void BindDataSet(DST* dataSet, NetworkContextBindMode mode) - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - m_dataSet = dataSet; - if (m_dataSet) - { - if (mode == NetworkContextBindMode::Authoritative) - { - /* - * If we are binding Field<> or BoundField<> on a component of an authoritative entity, - * then we want to bring over the value of the field in the component. This occurs during GetNetworkBinding(). - * - * Whereas on a client's (non-authoritative entities and their components) dataSet already has the desired value - * and should not be overwritten here. - */ - m_dataSet->Set(AZStd::move(m_value)); - } - m_value = DataType(); - } - } - - DataType* CacheValue() - { - if (m_dataSet) - { - m_value = m_dataSet->Get(); - } - return &m_value; - } - - const DataType& GetCachedValue() const - { - return m_value; - } - - private: - DataSet* m_dataSet; - DataType m_value; - }; - - /** - * \brief An extension of @NetBindable::Field with an ability to invoke a callback whenever the value changes on both authoritative and non-authoritative components. - * Or in other terms, on both the server and clients (when GridMate is setup to run in server-authoritative mode). - * - * \tparam DataType data type, same as @NetBindable::Field - * \tparam InterfaceType Component type class that holds this @BoundField - * \tparam FuncPtr member function pointer to the callback to invoke when this value is updated on non-authoritative components. - * \tparam MarshalerType optional, same as @NetBindable::Field - * \tparam ThrottlerType optional, same as @NetBindable::Field - * - * Example: - * - * BoundField m_testInt; - * - * And it must be reflected to SerializeContext _and_ NetworkContext just like @NetBindable::Field - * - * void TestFieldComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt) - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->Field("Test Int", &TestFieldComponent::m_testInt); - * } - * } - */ - template - class NetBindable::BoundField - : public NetBindable::Field - { - using BaseClass = NetBindable::Field; - friend class AZ::Internal::AzFrameworkNetBindableFieldContainer >; - public: - AZ_TYPE_INFO_LEGACY(BoundField, "{5151CEAF-6AC0-45D7-AEDF-8B6C46CE07B9}", DataType, InterfaceType, MarshalerType, ThrottlerType); - using DataSetType = typename DataSet::template BindInterface; - - explicit BoundField(const DataType& value = DataType()) - : BaseClass(value) - {} - ~BoundField() override = default; - - /* - * Disabling copy and move constructors in order to allow for a common use of fields, for example: - * m_field = m_field + 1; - */ - BoundField (const BoundField& other) = delete; - BoundField (BoundField&& other) = delete; - BoundField& operator= (const BoundField& other) = delete; - BoundField& operator= (BoundField&& other) = delete; - - operator DataType() const - { - return BaseClass::Get(); - } - - const DataType& operator*() const override - { - return BaseClass::Get(); - } - - BaseClass& operator=(const DataType& val) override - { - BaseClass::operator=(val); - return *this; - } - - BaseClass& operator=(const DataType&& val) override - { - BaseClass::operator=(val); - return *this; - } - - void Bind(DataSetBase* dataSet, NetworkContextBindMode mode) override - { - BaseClass::BindDataSet(static_cast(dataSet), mode); - } - - static void ConstructDataSet(void* mem, const char* name) - { - new (mem) DataSetType(name, DataType(), MarshalerType(), ThrottlerType()); - } - - static void DestructDataSet(void* mem) - { - DataSetType* dataSet = reinterpret_cast(mem); - dataSet->~DataSetType(); - } - }; - - class NetBindableRpcBase - { - public: - virtual ~NetBindableRpcBase() = default; - virtual void Bind(RpcBase* rpc) = 0; - virtual void Bind(NetBindable* handler) = 0; - }; - - /** - * \brief NetBindable::Rpc::Binder should be used for any RPC in a NetBindable that you want - * to be able to call remotely. If the object is not network bound, RPC - * calls will dispatch directly, as if the object was authoritative. - * - * \tparam Args any custom parameters for the remote procedure calls. - * - * Here is an example: - * - * // callback - * bool OnRpc(float value, const GridMate::RpcContext& rc); - * - * // Rpc declaration - * Rpc::Binder m_testRpc; - * - * Rpc needs to be reflected in NetworkContext like this: - * - * void TestRPCComponent::Reflect(AZ::ReflectContext* context) - * { - * if (AZ::SerializeContext* serialize = azrtti_cast(context)) - * { - * serialize->Class() - * ->Version(1); - * } - * - * if (AzFramework::NetworkContext* net = azrtti_cast(context)) - * { - * net->Class() - * ->RPC("Test RPC", &TestRPCComponent::m_testRpc); - * } - * } - * - * It can be invoked as if it was a method: - * - * m_testRpc(deltaTime); - */ - template - class NetBindable::Rpc - { - public: - /** - * \brief Binds rpc callback to a pointer to member function of AZ::Component derived from AzFramework::NetBindable - * See @NetBindable::Rpc - */ - template - class Binder - : public NetBindableRpcBase - { - friend class NetworkContext; - public: - using BindInterfaceType = typename GridMate::Rpc...>::template BindInterface; - - Binder() - : m_rpc(nullptr) - , m_instance(nullptr) - {} - - void Bind(RpcBase* rpc) override - { - m_rpc = static_cast(rpc); - m_instance = nullptr; - } - - void Bind(NetBindable* bindable) override - { - m_instance = static_cast(bindable); - m_rpc = nullptr; - } - - template - void operator()(CallArgs&& ... args) - { - AZ_Assert(m_instance || m_rpc, "Cannot call an RPC without either a local instance or a network bound handler, did you forget to register with NetworkContext()?"); - if (m_rpc) // connected to network - { - (*m_rpc)(AZStd::forward(args) ...); - } - else if (m_instance) // local dispatch - { - (*m_instance.*FuncPtr)(AZStd::forward(args) ..., RpcContext()); - } - } - - protected: - static void ConstructRpc(void* mem, const char* name) - { - new (mem) BindInterfaceType(name); - } - - static void DestructRpc(void*) { } - - private: - BindInterfaceType* m_rpc; - InterfaceType* m_instance; - }; - - Rpc() = delete; - }; -} // namespace AzFramework - -namespace AZ -{ - AZ_TYPE_INFO_TEMPLATE_WITH_NAME(AzFramework::NetBindable::Field, "Field", "{00D56FA7-F8BD-402B-97FB-0E2599897056}", AZ_TYPE_INFO_CLASS, AZ_TYPE_INFO_TYPENAME, AZ_TYPE_INFO_TYPENAME); - - namespace Internal - { - template - class AzFrameworkNetBindableFieldContainer - : public SerializeContext::IDataContainer - { - using ValueType = typename FieldType::ValueType; - public: - AzFrameworkNetBindableFieldContainer() - { - m_classElement.m_name = GetDefaultElementName(); - m_classElement.m_nameCrc = GetDefaultElementNameCrc(); - m_classElement.m_dataSize = sizeof(ValueType); - m_classElement.m_offset = 0; - m_classElement.m_azRtti = GetRttiHelper(); - m_classElement.m_flags = AZStd::is_pointer::value ? SerializeContext::ClassElement::FLG_POINTER : 0; - m_classElement.m_genericClassInfo = SerializeGenericTypeInfo::GetGenericInfo(); - m_classElement.m_typeId = SerializeGenericTypeInfo::GetClassTypeId(); - m_classElement.m_editData = nullptr; - } - - /// Returns the element generic (offsets are mostly invalid 0xbad0ffe0, there are exceptions). Null if element with this name can't be found. - virtual const SerializeContext::ClassElement* GetElement(AZ::u32 elementNameCrc) const override - { - if (elementNameCrc == m_classElement.m_nameCrc) - { - return &m_classElement; - } - return nullptr; - } - - bool GetElement(SerializeContext::ClassElement& classElement, const SerializeContext::DataElement& dataElement) const override - { - if (dataElement.m_nameCrc == m_classElement.m_nameCrc) - { - classElement = m_classElement; - return true; - } - return false; - } - - /// Enumerate elements in the array - virtual void EnumElements(void* instance, const ElementCB& cb) override - { - FieldType* field = reinterpret_cast(instance); - // We can't mess with the internal storage of the dataset safely, so we copy it into - // the field's local value cache temporarily, then hand that to the callback - // This will modify the local value cache, but that shouldn't matter as it will never - // be used as long as a dataset is bound - // If this turns out to be a perf problem due to copies of complex types, then - // the easy solution is to get DataSets to expose a pointer to their underlying - // data storage, and then we can return a pointer to that and modify it directly - // if the field is bound to the network - ValueType* valPtr = field->CacheValue(); - cb(valPtr, m_classElement.m_typeId, m_classElement.m_genericClassInfo ? m_classElement.m_genericClassInfo->GetClassData() : nullptr, &m_classElement); - // Ensure that the dataset is updated if changes happened - *field = *valPtr; - } - - void EnumTypes(const ElementTypeCB& cb) override - { - cb(m_classElement.m_typeId, &m_classElement); - } - - /// Return number of elements in the container. - virtual size_t Size(void*) const override - { - return 1; - } - - /// Returns the capacity of the container. Returns 0 for objects without fixed capacity. - virtual size_t Capacity(void* instance) const override - { - (void)instance; - return 1; - } - - /// Returns true if elements pointers don't change on add/remove. If false you MUST enumerate all elements. - virtual bool IsStableElements() const override { return true; } - - /// Returns true if the container is fixed size, otherwise false. - virtual bool IsFixedSize() const override { return true; } - - /// Returns if the container is fixed capacity, otherwise false - virtual bool IsFixedCapacity() const override { return true; } - - /// Returns true if the container is a smart pointer. - virtual bool IsSmartPointer() const override { return true; } - - /// Returns true if the container elements can be addressed by index, otherwise false. - virtual bool CanAccessElementsByIndex() const override { return false; } - - /// Reserve element - virtual void* ReserveElement(void* instance, const SerializeContext::ClassElement*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return field->CacheValue(); // return the local value, should be accurate as the field will be unbound at serialization time - } - - /// Get an element's address by its index (called before the element is loaded). - virtual void* GetElementByIndex(void*, const SerializeContext::ClassElement*, size_t) override - { - return nullptr; - } - - /// Store element - virtual void StoreElement(void* instance, void*) override - { - // force store the value again, just in case the field is bound to a dataset - FieldType* field = reinterpret_cast(instance); - *field = field->GetCachedValue(); - } - - /// Remove element in the container. - virtual bool RemoveElement(void* instance, const void*, SerializeContext*) override - { - FieldType* field = reinterpret_cast(instance); - *field = ValueType(); - return false; // you can't remove element from this container. - } - - /// Remove elements (removed array of elements) regardless if the container is Stable or not (IsStableElements) - virtual size_t RemoveElements(void* instance, const void**, size_t, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - return 0; // you can't remove elements from this container. - } - - /// Clear elements in the instance. - virtual void ClearElements(void* instance, SerializeContext*) override - { - RemoveElement(instance, nullptr, nullptr); - } - - SerializeContext::ClassElement m_classElement; ///< Generic class element covering as must as possible of the element (offset, and some other fields are invalid) - }; - } - - template - struct SerializeGenericTypeInfo< AzFramework::NetBindable::Field > - { - typedef typename AzFramework::NetBindable::Field ContainerType; - - class GenericClassNetBindableField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableField, "{C1D4DD97-5DD7-42ED-969C-7435F27F5D8C}"); - GenericClassNetBindableField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::Field", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; - - template - struct SerializeGenericTypeInfo< typename AzFramework::NetBindable::BoundField > - { - typedef typename AzFramework::NetBindable::BoundField ContainerType; - - class GenericClassNetBindableBoundField - : public GenericClassInfo - { - public: - AZ_TYPE_INFO(GenericClassNetBindableBoundField, "{EFD64FE7-9432-401A-B7A1-1767F4C5A7F0}"); - GenericClassNetBindableBoundField() - : m_classData{ SerializeContext::ClassData::Create("AzFramework::NetBindable::BoundField", GetSpecializedTypeId(), Internal::NullFactory::GetInstance(), nullptr, &m_containerStorage) } - { - } - - SerializeContext::ClassData* GetClassData() override - { - return &m_classData; - } - - size_t GetNumTemplatedArguments() override - { - return 1; - } - - const Uuid& GetTemplatedTypeId(size_t) override - { - return SerializeGenericTypeInfo::GetClassTypeId(); - } - - const Uuid& GetSpecializedTypeId() const override - { - return azrtti_typeid(); - } - - const Uuid& GetGenericTypeId() const override - { - return TYPEINFO_Uuid(); - } - - const Uuid& GetLegacySpecializedTypeId() const override - { - return AZ::AzTypeInfo::template Uuid(); - } - - void Reflect(SerializeContext* serializeContext) - { - if (serializeContext) - { - serializeContext->RegisterGenericClassInfo(GetSpecializedTypeId(), this, &AnyTypeInfoConcept::CreateAny); - if (GenericClassInfo* containerGenericClassInfo = m_containerStorage.m_classElement.m_genericClassInfo) - { - containerGenericClassInfo->Reflect(serializeContext); - } - } - } - - protected: - Internal::AzFrameworkNetBindableFieldContainer m_containerStorage; - SerializeContext::ClassData m_classData; - }; - - using ClassInfoType = GenericClassNetBindableBoundField; - - static ClassInfoType* GetGenericInfo() - { - return GetCurrentSerializeContextModule().CreateGenericClassInfo(); - } - - static const Uuid& GetClassTypeId() - { - return GetGenericInfo()->GetClassData()->m_typeId; - } - }; -} - -#endif // AZFRAMEWORK_NET_BINDABLE_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp deleted file mode 100644 index 90613daabe..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.cpp +++ /dev/null @@ -1,287 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - void NetBindingComponent::Reflect(AZ::ReflectContext* reflection) - { - NetBindable::Reflect(reflection); - - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ; - - AZ::EditContext* editContext = serializeContext->GetEditContext(); - - if (editContext) - { - editContext->Class( - "Network Binding", "The Network Binding component marks an entity as able to be replicated across the network") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Networking") - ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/NetBinding.svg") - ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Icons/Components/Viewport/NetBinding.png") - ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://docs.aws.amazon.com/lumberyard/latest/userguide/component-network-binding.html") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Game", 0x232b318c)); - } - } - - AZ::BehaviorContext* behaviorContext = azrtti_cast(reflection); - - if (behaviorContext) - { - behaviorContext->EBus("NetBindingHandlerBus") - ->Event("IsEntityBoundToNetwork", &NetBindingHandlerBus::Events::IsEntityBoundToNetwork) - ->Event("IsEntityAuthoritative", &NetBindingHandlerBus::Events::IsEntityAuthoritative) - - // Desired, but currently unsupported events. - // Seems to be an unsupported type(AZ::u16) - //->Event("SetReplicaPriority", &NetBindingHandlerBus::Events::SetReplicaPriority) - //->Event("GetReplicaPriority", &NetBindingHandlerBus::Events::GetReplicaPriority) - ; - } - - // We also need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingComponentChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - - NetBindingComponent::NetBindingComponent() - : m_isLevelSliceEntity(false) - { - } - - void NetBindingComponent::Activate() - { - NetBindingHandlerBus::Handler::BusConnect(GetEntityId()); - - if (!IsEntityBoundToNetwork()) - { - bool shouldBind = false; - NetBindingSystemBus::BroadcastResult( shouldBind, &NetBindingSystemBus::Events::ShouldBindToNetwork); - if (shouldBind) - { - BindToNetwork(nullptr); - } - else - { - /* - * This is the Editor path. We still need to call NetBindable::NetInit() in order - * to initialize NetworkContext Fields and RPCs, so that they behave as - * authoritative in game editor mode. Without this call RPCs callbacks won't invoke inside the Editor. - * For example: - * - * static void Reflect(...) - * { - * NetworkContext->Class()->RPC("my rpc", &MyNetworkComponent::m_myRpc); - * } - * ... - * m_myRpc(); // <--- will not invoke the callback inside the Editor unless NetInit() is called below. - */ - for (Component* component : GetEntity()->GetComponents()) - { - if (NetBindable* netBindable = azrtti_cast(component)) - { - netBindable->NetInit(); - } - } - } - } - } - - void NetBindingComponent::Deactivate() - { - NetBindingHandlerBus::Handler::BusDisconnect(); - if (IsEntityBoundToNetwork()) - { - static_cast(m_chunk.get())->SetBinding(nullptr); - if (m_chunk->IsMaster()) - { - m_chunk->GetReplica()->Destroy(); - } - m_chunk = nullptr; - } - } - - bool NetBindingComponent::IsEntityBoundToNetwork() - { - return m_chunk && m_chunk->GetReplica(); - } - - bool NetBindingComponent::IsEntityAuthoritative() - { - return !m_chunk || m_chunk->IsMaster(); - } - - void NetBindingComponent::BindToNetwork(GridMate::ReplicaPtr bindTo) - { - AZ_Assert(!IsEntityBoundToNetwork(), "We shouldn't be bound to the network if the network is just starting!"); - - if (bindTo) - { - NetBindingComponentChunkPtr bindingChunk = bindTo->FindReplicaChunk(); - AZ_Assert(bindingChunk, "Can't find NetBindingComponentChunk!"); - m_chunk = bindingChunk; - bindingChunk->SetBinding(this); - - GridMate::Replica* replica = bindingChunk->GetReplica(); - size_t nChunks = replica->GetNumChunks(); - size_t nBindings = bindingChunk->m_bindMap.Get().size(); - AZ_Assert(nChunks == nBindings, "Number of chunks received is not the same as the size of the bind map!"); - nBindings = AZ::GetMin(nBindings, nChunks); - for (size_t i = 0; i < nBindings; ++i) - { - AZ::ComponentId bindToId = bindingChunk->m_bindMap.Get()[i]; - if (bindToId != AZ::InvalidComponentId) - { - AZ::Component* component = GetEntity()->FindComponent(bindToId); - NetBindable* netBindable = azrtti_cast(component); - AZ_Assert(netBindable, "Can't find net bindable component with id %llu to be bound to chunk type %s!", bindToId, replica->GetChunkByIndex(i)->GetDescriptor()->GetChunkName()); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->SetNetworkBinding(replica->GetChunkByIndex(i)); - } - } - } - } - else - { - GridMate::ReplicaPtr replica = GridMate::Replica::CreateReplica(GetEntity()->GetName().c_str()); - NetBindingComponentChunk* chunk = GridMate::CreateReplicaChunk(); - m_chunk = chunk; - chunk->SetBinding(this); - replica->AttachReplicaChunk(chunk); - - chunk->m_bindMap.Modify([&](AZStd::vector& bindMap) - { - // Mark the chunks already in the replica as non-components. - bindMap.resize(replica->GetNumChunks(), AZ::InvalidComponentId); - - // Collect the bindings and add the to the replica - AZ::Entity* entity = GetEntity(); - for (Component* component : entity->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - GridMate::ReplicaChunkPtr bindingChunk = netBindable->GetNetworkBinding(); - if (bindingChunk) - { - bindMap.push_back(component->GetId()); - replica->AttachReplicaChunk(bindingChunk); - } - } - } - return true; - }); - - // Add replica to session replica manager (may be deferred) - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::AddReplicaMaster, GetEntity(), replica); - } - } - - void NetBindingComponent::UnbindFromNetwork() - { - if (m_chunk) - { - for (Component* component : GetEntity()->GetComponents()) - { - NetBindable* netBindable = azrtti_cast(component); - if (netBindable && netBindable->IsSyncEnabled()) - { - netBindable->UnbindFromNetwork(); - } - } - - NetBindingComponentChunkPtr chunk = static_cast(m_chunk.get()); - chunk->SetBinding(nullptr); - m_chunk = nullptr; - if (chunk->IsProxy()) - { - EntityContextId contextId = EntityContextId::CreateNull(); - EntityIdContextQueryBus::EventResult( contextId, GetEntityId(), &EntityIdContextQueryBus::Events::GetOwningContextId); - if (contextId.IsNull()) - { - delete GetEntity(); - } - else if (!IsLevelSliceEntity()) - { - NetBindingSystemBus::Broadcast( &NetBindingSystemBus::Events::UnbindGameEntity, GetEntityId(), m_sliceInstanceId); - } - } - } - } - - void NetBindingComponent::MarkAsLevelSliceEntity() - { - AZ_Assert(!IsEntityBoundToNetwork(), "MarkAsLevelSliceEntity() has to be called before the entity is bound to the network!"); - m_isLevelSliceEntity = true; - } - - void NetBindingComponent::SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - m_sliceInstanceId = sliceInstanceId; - } - - void NetBindingComponent::RequestEntityChangeOwnership(GridMate::PeerId peerId) - { - if (m_chunk && m_chunk->GetReplica()) - { - m_chunk->GetReplica()->RequestChangeOwnership(peerId); - } - } - - void NetBindingComponent::SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) - { - if (m_chunk) - { - m_chunk->SetPriority(replicaPriority); - } - } - - GridMate::ReplicaPriority NetBindingComponent::GetReplicaPriority() const - { - if (m_chunk && m_chunk->GetReplica()) - { - return m_chunk->GetReplica()->GetPriority(); - } - else - { - AZ_Error("NetBindingComponent",false,"Trying to gather ReplicaPriority without having a Replica."); - return GridMate::k_replicaPriorityLowest; - } - } - - bool NetBindingComponent::IsLevelSliceEntity() const - { - return m_isLevelSliceEntity; - } -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h deleted file mode 100644 index 5f4ec1c7f3..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponent.h +++ /dev/null @@ -1,85 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_H - -#include -#include - -namespace AzFramework -{ - /** - * NetBindingComponent enables network synchronization for the entity. - * It works in conjunction with NetBindingComponentChunk and NetBindingSystemComponent - * to perform network binding and notifies other components on the entity to bind - * their ReplicaChunks via the NetBindable interface. - * - * Entities bound to proxy replicas will be automatically destroyed when they are - * unbound from the network. - */ - class NetBindingComponent - : public AZ::Component - , public NetBindingHandlerBus::Handler - { - friend class NetBindingComponentChunk; - - public: - AZ_COMPONENT(NetBindingComponent, "{E9CA5D63-ED2D-4B59-B3C4-EBCD4A0013E4}", NetBindingHandlerInterface); - - NetBindingComponent(); - - protected: - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ReplicaChunkService", 0xf86b88a8)); - } - - /////////////////////////////////////////////////////////////////////// - // AZ::Component - static void Reflect(AZ::ReflectContext* reflection); - void Activate() override; - void Deactivate() override; - /////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // NetBindingHandlerBus::Handler - void BindToNetwork(GridMate::ReplicaPtr bindTo) override; - void UnbindFromNetwork() override; - bool IsEntityBoundToNetwork() override; - bool IsEntityAuthoritative() override; - void MarkAsLevelSliceEntity() override; - void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) override; - - void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) override; - GridMate::ReplicaPriority GetReplicaPriority() const override; - /////////////////////////////////////////////////////////////////////// - - //! Returns if the entity belongs to the level slice for binding purposes. - bool IsLevelSliceEntity() const; - - //! Points to the NetBindingComponentChunk counterpart. - GridMate::ReplicaChunkPtr m_chunk; - bool m_isLevelSliceEntity; - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp deleted file mode 100644 index 6ebfe63507..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.cpp +++ /dev/null @@ -1,254 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - NetBindingComponentChunk::SpawnInfo::SpawnInfo() - : m_runtimeEntityId(AZ::EntityId::InvalidEntityId) - , m_owningContextId(UnspecifiedNetBindingContextSequence) - , m_staticEntityId(AZ::EntityId::InvalidEntityId) - , m_sliceInstanceId(UnspecifiedSliceInstanceId) - , m_sliceAssetId(UnspecifiedSliceInstanceId, 0) - { - } - - bool NetBindingComponentChunk::SpawnInfo::operator==(const SpawnInfo& rhs) - { - return m_owningContextId == rhs.m_owningContextId - && m_runtimeEntityId == rhs.m_runtimeEntityId - && m_staticEntityId == rhs.m_staticEntityId - && m_serializedState == rhs.m_serializedState - && m_sliceAssetId == rhs.m_sliceAssetId; - } - - bool NetBindingComponentChunk::SpawnInfo::ContainsSerializedState() const - { - return !m_serializedState.empty(); - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data) - { - wb.Write(data.m_owningContextId, GridMate::VlqU32Marshaler()); - wb.Write(data.m_runtimeEntityId); - - bool useSerializedState = data.ContainsSerializedState(); - wb.Write(useSerializedState); - if (useSerializedState) - { - wb.Write(data.m_serializedState); - } - else - { - wb.Write(data.m_sliceAssetId); - wb.Write(data.m_staticEntityId); - wb.Write(data.m_sliceInstanceId); - } - } - - void NetBindingComponentChunk::SpawnInfo::Marshaler::Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb) - { - rb.Read(data.m_owningContextId, GridMate::VlqU32Marshaler()); - rb.Read(data.m_runtimeEntityId); - - bool hasSerializedState = false; - rb.Read(hasSerializedState); - if (hasSerializedState) - { - rb.Read(data.m_serializedState); - } - else - { - rb.Read(data.m_sliceAssetId); - rb.Read(data.m_staticEntityId); - rb.Read(data.m_sliceInstanceId); - } - } - - NetBindingComponentChunk::NetBindingComponentChunk() - : m_bindingComponent(nullptr) - , m_spawnInfo("SpawnInfo") - , m_bindMap("ComponentBindMap") - { - m_spawnInfo.SetMaxIdleTime(0.f); - m_bindMap.SetMaxIdleTime(0.f); - } - - void NetBindingComponentChunk::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (IsMaster()) - { - // Get and store entity spawn data - AZ_Assert(m_bindingComponent, "Entity binding is invalid!"); - - m_spawnInfo.Modify([&](SpawnInfo& spawnInfo) - { - spawnInfo.m_runtimeEntityId = static_cast(m_bindingComponent->GetEntity()->GetId()); - - bool isProceduralEntity = true; - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - - EntityContextId contextId = EntityContextId::CreateNull(); - const AZ::EntityId bindingComponentEntityId = m_bindingComponent->GetEntityId(); - EntityIdContextQueryBus::EventResult(contextId, bindingComponentEntityId, - &EntityIdContextQueryBus::Events::GetOwningContextId); - if (!contextId.IsNull()) - { - EBUS_EVENT_RESULT(spawnInfo.m_owningContextId, NetBindingSystemBus, GetCurrentContextSequence); - SliceEntityRequestBus::EventResult(sliceInfo, bindingComponentEntityId, - &SliceEntityRequestBus::Events::GetOwningSlice); - bool isDynamicSliceEntity = sliceInfo.IsValid(); - - isProceduralEntity = !m_bindingComponent->IsLevelSliceEntity() && !isDynamicSliceEntity; - } - - if (isProceduralEntity) - { - // write cloning info - AZ::SerializeContext* sc = nullptr; - EBUS_EVENT_RESULT(sc, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(sc, "Can't find SerializeContext!"); - AZ::IO::ByteContainerStream> spawnDataStream(&spawnInfo.m_serializedState); - AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&spawnDataStream, *sc, AZ::DataStream::ST_BINARY); - objStream->WriteClass(m_bindingComponent->GetEntity()); - objStream->Finalize(); - } - else - { - // write slice info - if (sliceInfo.IsValid()) - { - AZ::Data::AssetId sliceAssetId = sliceInfo.GetReference()->GetSliceAsset().GetId(); - spawnInfo.m_sliceAssetId = AZStd::make_pair(sliceAssetId.m_guid, sliceAssetId.m_subId); - } - if (sliceInfo.GetInstance()) - { - spawnInfo.m_sliceInstanceId = sliceInfo.GetInstance()->GetId(); - } - - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, m_bindingComponent->GetEntity()->GetId()); - spawnInfo.m_staticEntityId = static_cast(staticEntityId); - } - - return true; - }); - } - else - { - AZ::EntityId runtimeEntityId(m_spawnInfo.Get().m_runtimeEntityId); - NetBindingContextSequence owningContextId = m_spawnInfo.Get().m_owningContextId; - - //TODO Move to Filter Hook - // Reject and cancel sessions with duplicate MachineIds? - // Reject and cancel sessions with duplicate entity ID creation requests? - //Check MachineId collision - bool collision = AZ::Entity::GetProcessSignature() == (m_spawnInfo.Get().m_runtimeEntityId & 0xFFFFFFFF); - AZ_Error("GridMate", !collision, "Replica received with duplicate Entity Machine IDs. Ignoring"); - - if (!collision) - { - //Check EntityID collision - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, runtimeEntityId); - - /* - * Only false if no machine ID collision and no entity ID collision - * And the entity is already active, it's possible the entity already exists in deactivated state as a cache mechanism - */ - collision = (entity != nullptr) && (entity->GetState() == AZ::Entity::State::Active); - } - - /** - * Special case - static entities should not count as duplicates. - * Static entities are loaded with the level and will be bounded here. - */ - if (collision) - { - AZ::EntityId staticEntityId; - EBUS_EVENT_RESULT(staticEntityId, NetBindingSystemBus, GetStaticIdFromEntityId, runtimeEntityId); - if (staticEntityId == runtimeEntityId) - { - collision = false; - } - } - - if (!collision) //Ignore duplicate runtime entity IDs - { - if (m_spawnInfo.Get().ContainsSerializedState()) - { - // Spawn the entity from stream input data - AZ::IO::MemoryStream spawnData(m_spawnInfo.Get().m_serializedState.data(), m_spawnInfo.Get().m_serializedState.size()); - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromStream, spawnData, runtimeEntityId, GetReplicaId(), owningContextId); - } - else - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = owningContextId; - spawnContext.m_sliceAssetId = AZ::Data::AssetId(m_spawnInfo.Get().m_sliceAssetId.first, m_spawnInfo.Get().m_sliceAssetId.second); - spawnContext.m_runtimeEntityId = runtimeEntityId; - spawnContext.m_staticEntityId = AZ::EntityId(m_spawnInfo.Get().m_staticEntityId); - spawnContext.m_sliceInstanceId = m_spawnInfo.Get().m_sliceInstanceId; - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, GetReplicaId(), spawnContext); - } - } - else //Fail early to prevent unnecessary spawning of duplicate entity IDs - { - //Misconfiguration or potential cheating/DoS? - AZ_Warning("NetBinding", false, "Received duplicate Entity ID %llu. Ignoring.", runtimeEntityId); - } - } - } - - void NetBindingComponentChunk::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - if (m_bindingComponent) - { - m_bindingComponent->UnbindFromNetwork(); - } - } - - bool NetBindingComponentChunk::AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) - { - bool result = true; - - if (m_bindingComponent) - { - EBUS_EVENT_ID_RESULT(result, m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityAcceptChangeOwnership, requestor, rc); - } - - return result; - } - - void NetBindingComponentChunk::OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) - { - if (m_bindingComponent) - { - EBUS_EVENT_ID(m_bindingComponent->GetEntityId(), NetBindingEventsBus, OnEntityChangeOwnership, rc); - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h deleted file mode 100644 index 5a0f023fa2..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingComponentChunk.h +++ /dev/null @@ -1,112 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#define AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H - -#include -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindingComponent; - class NetBindingComponentChunkDescriptor; - - /** - * NetBindingComponentChunk is the counterpart of NetBindingComponent on the network side. - * It contains entity spawn data. It is created by NetBindingComponent during network - * binding on the master and initiates entity creation and binding on the proxy side. - */ - class NetBindingComponentChunk - : public GridMate::ReplicaChunk - { - friend NetBindingComponent; - friend NetBindingComponentChunkDescriptor; - - public: - AZ_CLASS_ALLOCATOR(NetBindingComponentChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingComponentChunk"; } - - NetBindingComponentChunk(); - - void SetBinding(NetBindingComponent* bindingComponent) { m_bindingComponent = bindingComponent; } - NetBindingComponent* GetBinding() const { return m_bindingComponent; } - - protected: - /////////////////////////////////////////////////////////////////////// - // ReplicaChunk - bool IsReplicaMigratable() override { return true; } - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - bool AcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) override; - void OnReplicaChangeOwnership(const GridMate::ReplicaContext& rc) override; - /////////////////////////////////////////////////////////////////////// - - NetBindingComponent* m_bindingComponent; - - class SpawnInfo - { - public: - class Marshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, const SpawnInfo& data); - void Unmarshal(SpawnInfo& data, GridMate::ReadBuffer& rb); - }; - - class Throttle - { - public: - //! Always return true because SpawnInfo never changes - bool WithinThreshold(const SpawnInfo&) const { return true; } - void UpdateBaseline(const SpawnInfo& baseline) { (void)baseline; } - }; - - SpawnInfo(); - - bool operator==(const SpawnInfo& rhs); - - bool ContainsSerializedState() const; - - /** - * \brief Same as m_staticEntityId on authoritative entity with master replica - */ - AZ::u64 m_runtimeEntityId; - NetBindingContextSequence m_owningContextId; - AZStd::vector m_serializedState; - - /** - * \brief EntityId of authoritative entity with master replica - */ - AZ::u64 m_staticEntityId; - - AZStd::pair m_sliceAssetId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - GridMate::DataSet m_spawnInfo; - GridMate::DataSet > m_bindMap; - }; - typedef AZStd::intrusive_ptr NetBindingComponentChunkPtr; -} // namespace AZ - -#endif // AZFRAMEWORK_NET_BINDING_COMPONENT_CHUNK_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h deleted file mode 100644 index f3089947dc..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingEventsBus.h +++ /dev/null @@ -1,51 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#define AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H - -#include -#include -#include - -namespace AzFramework -{ - /** - * NetBindingEventsBus - * Throws networking related entity events - */ - class NetBindingEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingEvents() {} - - /** - * Called on authoritative(Master) entity when ownership of this entity is about to be transferred to another peer - * Returning false from this call will result in denying request for ownership transfer - */ - virtual bool OnEntityAcceptChangeOwnership(GridMate::PeerId requestor, const GridMate::ReplicaContext& rc) { (void)requestor; (void)rc; return true; } - - /** - * Called when ownership transfer of an entity is finished. - */ - virtual void OnEntityChangeOwnership(const GridMate::ReplicaContext& rc) { (void)rc; } - }; - - typedef AZ::EBus NetBindingEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_EVENTS_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h deleted file mode 100644 index 55fa4c0217..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingHandlerBus.h +++ /dev/null @@ -1,112 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#define AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H - -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * The NetBindingSystemComponent notifies net binding handlers of binding events on this bus. - * The net binding component implements this interface and listens on the NetBindingHandlerBus. - */ - class NetBindingHandlerInterface - : public AZ::EBusTraits - { - public: - AZ_RTTI(NetBindingHandlerInterface, "{9F84E9FE-81A0-4105-9C51-6C42C83FECAF}"); - - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; - typedef AZ::EntityId BusIdType; - - virtual ~NetBindingHandlerInterface() {} - - /** - * Called to let the entity know that it should bind to the network. - * If bindTo is set, it means that the entity is a proxy and the handler - * should bind the entity to the specified - * replica, otherwise it should bind to a new replica and add it via - * NetBindingSystemBus::AddReplicaMaster. - */ - virtual void BindToNetwork(GridMate::ReplicaPtr bindTo) = 0; - - /** - * Called to let the entity know that it should unbind from the network. - */ - virtual void UnbindFromNetwork() = 0; - - /** - * Returns true if the entity is bound to the network. - */ - virtual bool IsEntityBoundToNetwork() = 0; - - /** - * Returns true if the entity is authoritative on the local node. - */ - virtual bool IsEntityAuthoritative() = 0; - - /** - * Flags the entity as part of the level slice. - */ - virtual void MarkAsLevelSliceEntity() = 0; - - /** - * Set the slice instance id that this entity was spawned by and belongs to. - */ - virtual void SetSliceInstanceId(const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - - /** - * Sets the Replica Priority - */ - virtual void SetReplicaPriority(GridMate::ReplicaPriority replicaPriority) = 0; - - /** - * Request entity ownership to a given peer (by default to local peer) - */ - virtual void RequestEntityChangeOwnership(GridMate::PeerId peerId = GridMate::InvalidReplicaPeerId) = 0; - - /** - * Gets the Replica Priority - */ - virtual GridMate::ReplicaPriority GetReplicaPriority() const = 0; - }; - typedef AZ::EBus NetBindingHandlerBus; - - /** - * Set of queries that might want to be made about the networking system - * mainly wraps up EBus calls to keep the implementing code a bit more readable - */ - class NetQuery - { - public: - AZ_RTTI(NetQuery, "{AA4C5699-889D-4A73-9AD2-53EB03D8BB99}"); - - virtual ~NetQuery() = default; - - static AZ_FORCE_INLINE bool IsEntityAuthoritative(AZ::EntityId entityId) - { - bool result = true; - EBUS_EVENT_ID_RESULT(result,entityId,NetBindingHandlerBus,IsEntityAuthoritative); - return result; - } - }; - -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_HANDLER_BUS_H -#pragma once diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h deleted file mode 100644 index c26c6d6350..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemBus.h +++ /dev/null @@ -1,119 +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 - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H - -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - namespace IO - { - class GenericStream; - } -} - -namespace AzFramework -{ - const AZ::SliceComponent::SliceInstanceId UnspecifiedSliceInstanceId = AZ::Uuid::CreateNull(); - - /** - */ - typedef AZ::u32 NetBindingContextSequence; - const NetBindingContextSequence UnspecifiedNetBindingContextSequence = 0; - - /** - */ - struct NetBindingSliceContext - { - NetBindingContextSequence m_contextSequence; - AZ::Data::AssetId m_sliceAssetId; - AZ::EntityId m_staticEntityId; - AZ::EntityId m_runtimeEntityId; - /** - * \brief uniquely identifies the slice instance that this entity is being replicated from - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - }; - - /** - * The net binding system implements this interface and listens on the NetBindingSystemBus. - * - * Network binding is activated when OnNetworkSessionActivated event is received with the binding session, - * and is deactivated by the OnNetworkSessionDeactivated event. - */ - class NetBindingSystemInterface - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - virtual ~NetBindingSystemInterface() {} - - //! Returns true if a network session is available and entities should bind themselves to the network. - virtual bool ShouldBindToNetwork() = 0; - - //! Returns the current entity context sequence - virtual NetBindingContextSequence GetCurrentContextSequence() = 0; - - //! Get a level entity's static id. - virtual AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) = 0; - - //! Get a level entity's id based on the static id - virtual AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) = 0; - - //! Adds a bound replica to the network session as master. - virtual void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) = 0; - - //! Spawn and bind an entity from a slice - virtual void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) = 0; - - //! Spawn and bind an entity from stream - virtual void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) = 0; - - //! De-spawn an entity: deactivates or removes the entity. - /** - * /note @sliceInstanceId is the slice instance that the entity belongs to. If it's a level entity, then this should be AZ::Uuid::CreateNull() - */ - virtual void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) = 0; - }; - typedef AZ::EBus NetBindingSystemBus; - - class NetBindingSystemEvents - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - //! Notification that a network session is created - virtual void OnNetworkSessionCreated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is ready - virtual void OnNetworkSessionActivated(GridMate::GridSession* session) { (void)session; } - - //! Notification that a network session is no longer available - virtual void OnNetworkSessionDeactivated(GridMate::GridSession* session) { (void)session; } - }; - typedef AZ::EBus NetBindingSystemEventsBus; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_BUS_H diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp deleted file mode 100644 index 85081d1637..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.cpp +++ /dev/null @@ -1,66 +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 -#include - -namespace AzFramework -{ - NetBindingSystemComponent::NetBindingSystemComponent() - { - } - - NetBindingSystemComponent::~NetBindingSystemComponent() - { - } - - void NetBindingSystemComponent::Activate() - { - NetBindingSystemImpl::Init(); - } - - void NetBindingSystemComponent::Deactivate() - { - NetBindingSystemImpl::Shutdown(); - } - - void NetBindingSystemComponent::Reflect(AZ::ReflectContext* context) - { - NetBindingSystemImpl::Reflect(context); - - if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ; - - if (AZ::EditContext* editContext = serializeContext->GetEditContext()) - { - editContext->Class( - "NetBinding System", "Performs network binding for game entities.") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Category, "Engine") - ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b)) - ; - } - } - } - - void NetBindingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } - - void NetBindingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("NetBindingSystemService", 0xa0ad6656)); - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h deleted file mode 100644 index 03ff6aa86f..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemComponent.h +++ /dev/null @@ -1,53 +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. -* -*/ - -#ifndef AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#define AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H - -#include -#include - -namespace AZ -{ - class ReflectContext; -} - -namespace AzFramework -{ - /** - * NetBindingSystemComponent exposes NetBindingSystemImpl as a component - */ - class NetBindingSystemComponent - : public AZ::Component - , public NetBindingSystemImpl - { - friend class NetBindingSystemContextData; - public: - AZ_COMPONENT(NetBindingSystemComponent, "{B96548CC-0866-4BB3-A87B-BF0C4F69E8AC}"); - - NetBindingSystemComponent(); - ~NetBindingSystemComponent() override; - - ////////////////////////////////////////////////////////////////////////// - // Component overrides - void Activate() override; - void Deactivate() override; - static void Reflect(AZ::ReflectContext* context); - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - ////////////////////////////////////////////////////////////////////////// - }; -} // namespace AzFramework - -#endif // AZFRAMEWORK_NET_BINDING_SYSTEM_COMPONENT_H -#pragma once - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp deleted file mode 100644 index bb40432ffb..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.cpp +++ /dev/null @@ -1,957 +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 -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//#define Extra_Tracing -#undef Extra_Tracing - -#if defined(Extra_Tracing) -#include -#define AZ_ExtraTracePrintf(window, ...) AZ::Debug::Trace::Instance().Printf(window, __VA_ARGS__); -#else -#define AZ_ExtraTracePrintf(window, ...) -#endif - -namespace AzFramework -{ - const AZStd::chrono::milliseconds NetBindingSystemImpl::s_sliceBindingTimeout = AZStd::chrono::milliseconds(5000); - - namespace - { - NetBindingHandlerInterface* GetNetBindingHandler(AZ::Entity* entity) - { - NetBindingHandlerInterface* handler = nullptr; - for (AZ::Component* component : entity->GetComponents()) - { - handler = azrtti_cast(component); - if (handler) - { - break; - } - } - return handler; - } - } - - NetBindingSliceInstantiationHandler::~NetBindingSliceInstantiationHandler() - { - // m_bindRequests in NetBindingSystemImpl could be cleaned before slice instantiation finished - if (m_state == State::Spawning) - { - AzFramework::SliceInstantiationResultBus::Handler::BusDisconnect(); - SliceGameEntityOwnershipServiceRequestBus::Broadcast( - &SliceGameEntityOwnershipServiceRequests::CancelDynamicSliceInstantiation, m_ticket - ); - } - - for (AZ::Entity* entity : m_boundEntities) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Cleanup - deleting %llu\n", entity->GetId()); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entity->GetId()); - } - } - - void NetBindingSliceInstantiationHandler::InstantiateEntities() - { - if (m_sliceAssetId.IsValid()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "InstantiateEntities sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - - if (AZ::Data::AssetManager::IsReady()) - { - auto remapFunc = [bindingQueue=m_bindingQueue](AZ::EntityId originalId, bool /*isEntityId*/, const AZStd::function&) -> AZ::EntityId - { - auto iter = bindingQueue.find(originalId); - if (iter != bindingQueue.end()) - { - return iter->second.m_desiredRuntimeEntityId; - } - return AZ::Entity::MakeId(); - }; - - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().FindOrCreateAsset(m_sliceAssetId, AZ::Data::AssetLoadBehavior::Default); - - SliceGameEntityOwnershipServiceRequestBus::BroadcastResult(m_ticket, - &SliceGameEntityOwnershipServiceRequests::InstantiateDynamicSlice, asset, AZ::Transform::Identity(), remapFunc); - SliceInstantiationResultBus::Handler::BusConnect(m_ticket); - - m_state = State::Spawning; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "AssetManager was not ready when attempting to instantiate sliceid %s\n", - m_sliceInstanceId.ToString(false, false).c_str()); - InstantiationFailureCleanup(); - } - } - } - - bool NetBindingSliceInstantiationHandler::IsInstantiated() const - { - return m_state == State::Spawned; - } - - bool NetBindingSliceInstantiationHandler::IsANewSliceRequest() const - { - return m_state == State::NewRequest && m_sliceAssetId.IsValid() && !m_ticket.IsValid(); - } - - bool NetBindingSliceInstantiationHandler::IsBindingComplete() const - { - return !SliceInstantiationResultBus::Handler::BusIsConnected() && m_bindingQueue.empty(); - } - - bool NetBindingSliceInstantiationHandler::HasActiveEntities() const - { - for (const AZ::Entity* entity : m_boundEntities) - { - if (entity->GetState() == AZ::Entity::State::Active) - { - return true; - } - } - - return false; - } - - void NetBindingSliceInstantiationHandler::OnSlicePreInstantiate(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - const auto& entityMapping = sliceAddress.GetInstance()->GetEntityIdToBaseMap(); - - const AZ::SliceComponent::EntityList& sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = entityMapping.find(sliceEntity->GetId()); - AZ_Assert(it != entityMapping.end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - - auto itBindRecord = m_bindingQueue.find(staticEntityId); - if (itBindRecord != m_bindingQueue.end()) - { - AZ_Assert(GetNetBindingHandler(sliceEntity), "Slice entity matched the static id of replicated entity, but there is no valid NetBindingHandlerInterface on it!"); - - itBindRecord->second.m_actualRuntimeEntityId = sliceEntity->GetId(); - } - else if (GetNetBindingHandler(sliceEntity)) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(sliceEntity->GetId())); - - BindRequest& request = m_bindingQueue[staticEntityId]; - request.m_desiredRuntimeEntityId = staticEntityId; - request.m_actualRuntimeEntityId = sliceEntity->GetId(); - request.m_requestTime = m_bindTime; - request.m_state = BindRequest::State::PlaceholderBind; - } - - sliceEntity->SetRuntimeActiveByDefault(false); - } - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiated(const AZ::Data::AssetId& /*sliceAssetId*/, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - CloseEntityMap(sliceAddress.GetInstance()->GetEntityIdMap()); - - const AZ::SliceComponent::EntityList sliceEntities = sliceAddress.GetInstance()->GetInstantiated()->m_entities; - for (AZ::Entity *sliceEntity : sliceEntities) - { - auto it = sliceAddress.GetInstance()->GetEntityIdToBaseMap().find(sliceEntity->GetId()); - AZ_Assert(it != sliceAddress.GetInstance()->GetEntityIdToBaseMap().end(), "Failed to retrieve static entity id for a slice entity!"); - const AZ::EntityId staticEntityId = it->second; - const auto itUnbound = m_bindingQueue.find(staticEntityId); - if (itUnbound == m_bindingQueue.end()) - { - /* - * Remove entities that aren't meant to be net bounded. - */ - if (!GetNetBindingHandler(sliceEntity)) - { - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, sliceEntity->GetId()); - continue; - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Adding %llu \n", sliceEntity->GetId()); - m_boundEntities.push_back(sliceEntity); - } - - m_state = State::Spawned; - } - - void NetBindingSliceInstantiationHandler::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) - { - SliceInstantiationResultBus::Handler::BusDisconnect(); - - AZ_UNUSED(sliceAssetId); - AZ_TracePrintf("NetBindingSystemImpl", "Failed to instantiate a slice %s!", sliceAssetId.ToString().c_str()); - - InstantiationFailureCleanup(); - } - - void NetBindingSliceInstantiationHandler::InstantiationFailureCleanup() - { - m_boundEntities.clear(); - m_bindingQueue.clear(); - - // With m_bindingQueue empty, this slice instance handler will be removed on the next tick of NetBindingSystemImpl - m_state = State::Failed; - } - - void NetBindingSliceInstantiationHandler::UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId) - { - AZ_Warning("NetBindingSystemImpl", !m_staticToRuntimeEntityMap.empty(), "An empty slice, really? static %llu", - static_cast(staticEntityId)); - - const auto actualRuntimeIter = m_staticToRuntimeEntityMap.find(staticEntityId); - if (actualRuntimeIter == m_staticToRuntimeEntityMap.end()) - { - AZ_Warning("NetBindingSystemImpl", false, "Wrong mapping, expected cache to have entity %llu for slice %s \n", - static_cast(staticEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - -#if defined(Extra_Tracing) - for (auto& item: m_staticToRuntimeEntityMap) - { - AZ_UNUSED(item); - AZ_ExtraTracePrintf("NetBindingSystemImpl", "mapping had %llu to %llu \n", - static_cast(item.first), - static_cast(item.second)); - } -#endif - - return; - } - - const AZ::EntityId actualRuntimeEntityId = actualRuntimeIter->second; - const auto itCache = AZStd::find_if(m_boundEntities.begin(), m_boundEntities.end(), [&actualRuntimeEntityId](AZ::Entity* entity) { - return entity->GetId() == actualRuntimeEntityId; - }); - - if (itCache != m_boundEntities.end()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "OnSlicePreInstantiate late bindRequest, slice %s, staticid %llu, spawned %llu\n", - m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(staticEntityId), - static_cast(actualRuntimeEntityId)); - - request.m_actualRuntimeEntityId = actualRuntimeEntityId; - request.m_desiredRuntimeEntityId = staticEntityId; - } - else - { - AZ_Warning("NetBindingSystemImpl", false, "Expected cache to have entity %llu for slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - m_sliceInstanceId.ToString(false, false).c_str()); - } - } - - void NetBindingSliceInstantiationHandler::CloseEntityMap( - const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap) - { - m_staticToRuntimeEntityMap.clear(); - for (auto& item : staticToRuntimeMap) - { - m_staticToRuntimeEntityMap[item.first] = item.second; - } - } - - NetBindingSystemContextData::NetBindingSystemContextData() - : m_bindingContextSequence("BindingContextSequence", UnspecifiedNetBindingContextSequence) - { - } - - void NetBindingSystemContextData::OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - AZ_Assert(system, "NetBindingSystemContextData requires a valid NetBindingSystemComponent to function!"); - system->OnContextDataActivated(this); - } - - void NetBindingSystemContextData::OnReplicaDeactivate(const GridMate::ReplicaContext& rc) - { - (void)rc; - NetBindingSystemImpl* system = static_cast(NetBindingSystemBus::FindFirstHandler()); - if (system) - { - system->OnContextDataDeactivated(this); - } - } - - - NetBindingSystemImpl::NetBindingSystemImpl() - : m_bindingSession(nullptr) - , m_currentBindingContextSequence(UnspecifiedNetBindingContextSequence) - , m_isAuthoritativeRootSliceLoad(false) - , m_overrideRootSliceLoadAuthoritative(false) - { - } - - NetBindingSystemImpl::~NetBindingSystemImpl() - { - } - - void NetBindingSystemImpl::Init() - { - NetBindingSystemBus::Handler::BusConnect(); - NetBindingSystemEventsBus::Handler::BusConnect(); - - // Start listening for game context events - EntityContextId gameContextId = EntityContextId::CreateNull(); - EBUS_EVENT_RESULT(gameContextId, GameEntityContextRequestBus, GetGameEntityContextId); - if (!gameContextId.IsNull()) - { - EntityContextEventBus::Handler::BusConnect(gameContextId); - } - } - - void NetBindingSystemImpl::Shutdown() - { - EntityContextEventBus::Handler::BusDisconnect(); - NetBindingSystemEventsBus::Handler::BusDisconnect(); - NetBindingSystemBus::Handler::BusDisconnect(); - - m_contextData.reset(); - } - - bool NetBindingSystemImpl::ShouldBindToNetwork() - { - return m_contextData && m_contextData->ShouldBindToNetwork(); - } - - NetBindingContextSequence NetBindingSystemImpl::GetCurrentContextSequence() - { - return m_currentBindingContextSequence; - } - - bool NetBindingSystemImpl::ReadyToAddReplica() const - { - return m_bindingSession && m_bindingSession->GetReplicaMgr(); - } - - void NetBindingSystemImpl::AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) - { - bool addReplica = ShouldBindToNetwork(); - AZ_Assert(addReplica, "Entities shouldn't be binding to the network right now!"); - if (addReplica) - { - if (ReadyToAddReplica()) - { - m_bindingSession->GetReplicaMgr()->AddMaster(replica); - } - else - { - m_addMasterRequests.push_back(AZStd::make_pair(entity->GetId(), replica)); - } - } - } - - - AZ::EntityId NetBindingSystemImpl::GetStaticIdFromEntityId(AZ::EntityId entityId) - { - AZ::EntityId staticId = entityId; // if no static id mapping is found, then the static id is the same as the runtime id - - // If entity came from a slice, try to get the mapping from it - AZ::SliceComponent::SliceInstanceAddress sliceInfo; - SliceEntityRequestBus::EventResult(sliceInfo, entityId, &SliceEntityRequestBus::Events::GetOwningSlice); - AZ::SliceComponent::SliceInstance* sliceInstance = sliceInfo.GetInstance(); - if (sliceInstance) - { - const auto it = sliceInstance->GetEntityIdToBaseMap().find(entityId); - if (it != sliceInstance->GetEntityIdToBaseMap().end()) - { - staticId = it->second; - } - } - - return staticId; - } - - AZ::EntityId NetBindingSystemImpl::GetEntityIdFromStaticId(AZ::EntityId staticEntityId) - { - AZ::EntityId runtimeId = AZ::EntityId(); - - // if we can find an entity with the static id, then the static id is the same as the runtime id. - AZ::Entity* entity = nullptr; - EBUS_EVENT(AZ::ComponentApplicationBus, FindEntity, staticEntityId); - if (entity) - { - runtimeId = staticEntityId; - } - - return runtimeId; - } - - void NetBindingSystemImpl::SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) - { - auto& sliceQueue = m_bindRequests[bindToContext.m_contextSequence]; - - const bool slicePresent = sliceQueue.find(bindToContext.m_sliceInstanceId) != sliceQueue.end(); - - auto iterSliceRequest = sliceQueue.insert_key(bindToContext.m_sliceInstanceId); - NetBindingSliceInstantiationHandler& sliceHandler = iterSliceRequest.first->second; - sliceHandler.m_sliceAssetId = bindToContext.m_sliceAssetId; - sliceHandler.m_sliceInstanceId = bindToContext.m_sliceInstanceId; - - BindRequest& request = sliceHandler.m_bindingQueue[bindToContext.m_staticEntityId]; - - if (!slicePresent) - { - request.m_state = BindRequest::State::FirstBindInSlice; - } - else - { - request.m_state = BindRequest::State::LateBind; - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "SpawnEntityFromSlice late, slice %s, static %llu, desired %llu, state %d \n", - bindToContext.m_sliceInstanceId.ToString(false, false).c_str(), - static_cast(bindToContext.m_staticEntityId), - static_cast(bindToContext.m_runtimeEntityId), - request.m_state); - - sliceHandler.m_bindTime = Now(); - - request.m_bindTo = bindTo; - request.m_desiredRuntimeEntityId = bindToContext.m_runtimeEntityId; - request.m_requestTime = Now(); - - if (sliceHandler.IsInstantiated()) - { - // The slice has been instantiated now, thus we have to use the cache to populated the request with the entity. - sliceHandler.UseCacheFor(request, bindToContext.m_staticEntityId); - } - } - - void NetBindingSystemImpl::SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) - { - auto& requestQueue = m_spawnRequests[addToContext]; - requestQueue.push_back(); - SpawnRequest& request = requestQueue.back(); - request.m_bindTo = bindTo; - request.m_useEntityId = useEntityId; - request.m_spawnDataBuffer.resize_no_construct(spawnData.GetLength()); - spawnData.Read(request.m_spawnDataBuffer.size(), request.m_spawnDataBuffer.data()); - } - - void NetBindingSystemImpl::OnNetworkSessionActivated(GridMate::GridSession* session) - { - AZ_Assert(!m_bindingSession, "We already have an active session! Was the previous session deactivated?"); - if (!m_bindingSession) - { - m_bindingSession = session; - - if (m_bindingSession->IsHost()) - { - GridMate::Replica* replica = CreateSystemReplica(); - session->GetReplicaMgr()->AddMaster(replica); - } - } - } - - void NetBindingSystemImpl::OnNetworkSessionDeactivated(GridMate::GridSession* session) - { - if (session == m_bindingSession) - { - m_bindingSession = nullptr; - } - } - - void NetBindingSystemImpl::UnbindGameEntity(AZ::EntityId entityId, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - if (!m_bindRequests.empty()) - { - const auto itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - const auto itSliceHandler = itCurrentContextQueue->second.find(sliceInstanceId); - if (itSliceHandler != itCurrentContextQueue->second.end()) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - for (AZ::Entity* entity : sliceHandler.m_boundEntities) - { - if (entity->GetId() == entityId) - { - entity->Deactivate(); - return; - } - } - - // clean any relevant bind requests as well - const auto bindQueueItem = sliceHandler.m_bindingQueue.find(entityId); - if (bindQueueItem != sliceHandler.m_bindingQueue.end()) - { - sliceHandler.m_bindingQueue.erase(bindQueueItem); - return; - } - } - } - } - } - - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Not in cache - deleting %llu \n", entityId); - EBUS_EVENT(GameEntityContextRequestBus, DestroyGameEntity, entityId); - } - - void NetBindingSystemImpl::OnEntityContextReset() - { - const bool isContextOwner = m_contextData && m_contextData->IsMaster() && m_bindingSession && m_bindingSession->IsHost(); - if (isContextOwner) - { - ++m_currentBindingContextSequence; - NetBindingSystemContextData* context = static_cast(m_contextData.get()); - context->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - } - - bool NetBindingSystemImpl::IsAuthoritateLoad() const - { - if (m_overrideRootSliceLoadAuthoritative) - { - return m_isAuthoritativeRootSliceLoad; - } - - return !m_bindingSession || m_bindingSession->IsHost(); - } - - void NetBindingSystemImpl::UpdateClock(float deltaTime) - { - m_currentTime += AZStd::chrono::milliseconds(aznumeric_cast(deltaTime * AZStd::milli::den)); - } - - AZStd::chrono::system_clock::time_point NetBindingSystemImpl::Now() const - { - return m_currentTime; - } - - void NetBindingSystemImpl::OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) - { - const bool isAuthoritativeLoad = IsAuthoritateLoad(); - - for (AZ::Entity* entity : contextEntities) - { - NetBindingHandlerInterface* netBinder = GetNetBindingHandler(entity); - if (netBinder) - { - netBinder->MarkAsLevelSliceEntity(); - } - - if (!isAuthoritativeLoad && netBinder) - { - entity->SetRuntimeActiveByDefault(false); - - auto& slicesQueue = m_bindRequests[GetCurrentContextSequence()]; - auto& sliceHandler = slicesQueue[UnspecifiedSliceInstanceId]; - BindRequest& request = sliceHandler.m_bindingQueue[entity->GetId()]; - request.m_actualRuntimeEntityId = entity->GetId(); - request.m_requestTime = Now(); - } - } - } - - void NetBindingSystemImpl::OnTick(float deltaTime, AZ::ScriptTimePoint time) - { - AZ_UNUSED(time); - - UpdateClock(deltaTime); - UpdateContextSequence(); - -#if defined(Extra_Tracing) - static AZ::Debug::Timer sTimer; - sTimer.Stamp(); -#endif - ProcessBindRequests(); -#if defined(Extra_Tracing) - const float seconds = sTimer.StampAndGetDeltaTimeInSeconds(); - - static float debugPeriod = 2.f; - static float accumulator = 0; - static float totalTimeTaken = 0; - static AZ::u32 totalTicks = 0; - accumulator += deltaTime; - totalTimeTaken += seconds; - totalTicks++; - - if (accumulator >= debugPeriod) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "ProcessBindRequests() took %f sec \n", totalTicks > 0 ? totalTimeTaken / totalTicks : 0); - - accumulator -= debugPeriod; - totalTimeTaken = 0; - totalTicks = 0; - } -#endif - - ProcessSpawnRequests(); - } - - int NetBindingSystemImpl::GetTickOrder() - { - return AZ::TICK_PLACEMENT + 1; - } - - void NetBindingSystemImpl::UpdateContextSequence() - { - NetBindingSystemContextData* contextChunk = static_cast(m_contextData.get()); - if (m_currentBindingContextSequence != contextChunk->m_bindingContextSequence.Get()) - { - m_currentBindingContextSequence = contextChunk->m_bindingContextSequence.Get(); - } - } - - GridMate::Replica* NetBindingSystemImpl::CreateSystemReplica() - { - AZ_Assert(m_bindingSession->IsHost(), "CreateSystemReplica should only be called on the host!"); - GridMate::Replica* replica = GridMate::Replica::CreateReplica("NetBindingSystem"); - NetBindingSystemContextData* contextChunk = GridMate::CreateReplicaChunk(); - replica->AttachReplicaChunk(contextChunk); - - return replica; - } - - void NetBindingSystemImpl::OnContextDataActivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(!m_contextData, "We already have our context!"); - m_contextData = contextData; - - // Make sure we always have the unspecified entry. This should also - // be the lower_bound in the map and assuming it is always there - // makes things simpler. - m_spawnRequests.insert(UnspecifiedNetBindingContextSequence); - m_bindRequests.insert(UnspecifiedNetBindingContextSequence); - - if (contextData->IsMaster()) - { - ++m_currentBindingContextSequence; - static_cast(contextData.get())->m_bindingContextSequence.Set(m_currentBindingContextSequence); - } - else - { - UpdateContextSequence(); - } - AZ::TickBus::Handler::BusConnect(); - EBUS_EVENT(AzFramework::NetBindingHandlerBus, BindToNetwork, nullptr); - } - - void NetBindingSystemImpl::OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData) - { - AZ_Assert(m_contextData == contextData, "This is not our context!"); - m_contextData = nullptr; - - AZ::TickBus::Handler::BusDisconnect(); - m_spawnRequests.clear(); - m_bindRequests.clear(); - m_addMasterRequests.clear(); - m_currentBindingContextSequence = UnspecifiedNetBindingContextSequence; - } - - void NetBindingSystemImpl::ProcessSpawnRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - const auto spawnFunc = [=](SpawnRequest& spawnData, AZ::EntityId useEntityId, bool addToContext) - { - AZ::Entity* proxyEntity = nullptr; - AZ::ObjectStream::ClassReadyCB readyCB([&](void* classPtr, const AZ::Uuid& classId, AZ::SerializeContext* sc) - { - (void)classId; - (void)sc; - proxyEntity = static_cast(classPtr); - }); - AZ::IO::ByteContainerStream > stream(&spawnData.m_spawnDataBuffer); - AZ::ObjectStream::LoadBlocking(&stream, *serializeContext, readyCB); - - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not spawn entity from stream %llu", useEntityId); - if (proxyEntity) - { - proxyEntity->SetId(useEntityId); - if (!BindAndActivate(proxyEntity, spawnData.m_bindTo, addToContext, AZ::Uuid::CreateNull())) - { - AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::EntityIdContextQueryBus::EventResult( - contextId, proxyEntity->GetId(), &AzFramework::EntityIdContextQueryBus::Events::GetOwningContextId); - - if (contextId.IsNull()) - { - delete proxyEntity; - } - else - { - GameEntityContextRequestBus::Broadcast( - &GameEntityContextRequestBus::Events::DestroyGameEntity, proxyEntity->GetId()); - } - - } - } - }; - - if (!m_spawnRequests.empty()) - { - SpawnRequestContextContainerType::iterator itContextQueue = m_spawnRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified (aka global entity) spawn queue!");// - - // Process requests for global entities (not part of any context) - SpawnRequestContainerType& globalQueue = itContextQueue->second; - for (SpawnRequest& request : globalQueue) - { - spawnFunc(request, request.m_useEntityId, false); - } - globalQueue.clear(); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - SpawnRequestContextContainerType::iterator itCurrentContextQueue = m_spawnRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_spawnRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any entities for the current context - if (itCurrentContextQueue != m_spawnRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (SpawnRequest& request : itCurrentContextQueue->second) - { - spawnFunc(request, request.m_useEntityId, true); - } - itCurrentContextQueue->second.clear(); - } - } - } - } - } - - void NetBindingSystemImpl::ProcessBindRequests() - { - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "NetBindingSystemComponent requires a valid SerializeContext in order to spawn entities!"); - - if (!m_bindRequests.empty()) - { - BindRequestContextContainerType::iterator itContextQueue = m_bindRequests.lower_bound(UnspecifiedNetBindingContextSequence); - AZ_Assert(itContextQueue->first == UnspecifiedNetBindingContextSequence, "We should always have the unspecified/global spawn queue!"); - - if (GetCurrentContextSequence() != UnspecifiedNetBindingContextSequence) - { - ++itContextQueue; - - // Clear any obsolete requests (any contexts below the current context sequence) - BindRequestContextContainerType::iterator itCurrentContextQueue = m_bindRequests.lower_bound(GetCurrentContextSequence()); - if (itContextQueue != itCurrentContextQueue) - { - m_bindRequests.erase(itContextQueue, itCurrentContextQueue); - } - - // Spawn any proxy entities for the current context - if (itCurrentContextQueue != m_bindRequests.end()) - { - if (itCurrentContextQueue->first == GetCurrentContextSequence()) - { - for (auto itSliceHandler = itCurrentContextQueue->second.begin(); itSliceHandler != itCurrentContextQueue->second.end(); /*++itSliceHandler*/) - { - NetBindingSliceInstantiationHandler& sliceHandler = itSliceHandler->second; - - // If this is a new slice request, instantiate it - if (sliceHandler.IsANewSliceRequest()) - { - sliceHandler.InstantiateEntities(); - } - /* - * A slice instance is kept alive for caching purposes. As we check each bind request for its readiness, - * we are also going to check if the slice instance itself has become inactive and needs to be removed. - */ - bool mightBeInactiveSlice = true; - if (sliceHandler.m_bindingQueue.empty() && sliceHandler.HasActiveEntities()) - { - // The slice instance is spawned and full bound. - mightBeInactiveSlice = false; - } - - // If the entity is ready to be bound to the network, bind it. - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. We don't have a very good pipeline to prevent these slices from being authored, so if we - // encounter them, we will delete them after a timeout. - for (auto itRequest = sliceHandler.m_bindingQueue.begin(); itRequest != sliceHandler.m_bindingQueue.end(); /*++itRequest*/) - { - BindRequest& request = itRequest->second; - - if (request.m_bindTo != GridMate::InvalidReplicaId && request.m_actualRuntimeEntityId.IsValid()) - { - AZ::Entity* proxyEntity = nullptr; - EBUS_EVENT_RESULT(proxyEntity, AZ::ComponentApplicationBus, FindEntity, request.m_actualRuntimeEntityId); - AZ_Warning("NetBindingSystemImpl", proxyEntity, "Could not find entity for binding %llu", request.m_actualRuntimeEntityId); - if (proxyEntity) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "BindAndActivate desired id %llu, actual %llu, slice %s \n", - static_cast(request.m_desiredRuntimeEntityId), - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - BindAndActivate(proxyEntity, request.m_bindTo, false, sliceHandler.m_sliceInstanceId); - } - itRequest = sliceHandler.m_bindingQueue.erase(itRequest); - - // The slice instance is not fully bound. It may remain for a while for caching purposes. - mightBeInactiveSlice = false; - } - else if (AZStd::chrono::milliseconds(Now() - request.m_requestTime) > s_sliceBindingTimeout) - { - // If the real request never showed up, then no need for a trace - if (request.m_state == BindRequest::State::FirstBindInSlice || - request.m_state == BindRequest::State::LateBind) - { - AZ_TracePrintf("NetBindingSystemImpl", "Entity with static id [%llu], slice [%s]\n is still unbound after %llu ms. Discarding unbound entity.\n", - static_cast(request.m_actualRuntimeEntityId), - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str(), - s_sliceBindingTimeout.count()); - } - - switch (sliceHandler.m_state) - { - case NetBindingSliceInstantiationHandler::State::NewRequest: - case NetBindingSliceInstantiationHandler::State::Spawning: - // The slice instance isn't ready yet. We will wait to consider the timing logic until it is ready. - mightBeInactiveSlice = false; - break; - case NetBindingSliceInstantiationHandler::State::Spawned: - case NetBindingSliceInstantiationHandler::State::Failed: - // Now the timing logic for removing the slice instance becomes valid. - mightBeInactiveSlice = true; - break; - default: - break; - } - - ++itRequest; - } - else - { - mightBeInactiveSlice = false; - ++itRequest; - } - } - - if (mightBeInactiveSlice && !sliceHandler.HasActiveEntities()) - { - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Removing inactive slice %s \n", - sliceHandler.m_sliceInstanceId.ToString(false, false).c_str()); - - itSliceHandler = itCurrentContextQueue->second.erase(itSliceHandler); - } - else - { - ++itSliceHandler; - } - } - } - } - } - } - - // Spawn replicas for any local entities that are still valid - for (auto& addRequest : m_addMasterRequests) - { - AZ::Entity* entity = nullptr; - EBUS_EVENT_RESULT(entity, AZ::ComponentApplicationBus, FindEntity, addRequest.first); - if (entity) - { - m_bindingSession->GetReplicaMgr()->AddMaster(addRequest.second); - } - } - m_addMasterRequests.clear(); - } - - bool NetBindingSystemImpl::BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, - const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) - { - bool success = false; - - if ( ShouldBindToNetwork() ) - { - const GridMate::ReplicaPtr bindTo = m_contextData->GetReplicaManager()->FindReplica(replicaId); - if (bindTo) - { - if (addToContext) - { - EBUS_EVENT(GameEntityContextRequestBus, AddGameEntity, entity); - } - - if (entity->GetState() == AZ::Entity::State::Constructed) - { - entity->Init(); - } - - NetBindingHandlerInterface* binding = GetNetBindingHandler(entity); - AZ_Warning("NetBindingSystemImpl", binding, "Can't find NetBindingComponent on entity %llu (%s)!", static_cast(entity->GetId()), entity->GetName().c_str()); - if (binding) - { - binding->BindToNetwork(bindTo); - binding->SetSliceInstanceId(sliceInstanceId); - - entity->Activate(); - success = true; - } - } - else - { - // NOTE: It is possible for entities spawned from a slice containing multiple entities with net binding - // to never receive their replica counterpart, either because the replica was destroyed, or was interest - // filtered. - AZ_ExtraTracePrintf("NetBindingSystemImpl", "Failed to bind entity %llu - could not find replica %u", entity->GetId(), replicaId); - } - } - - return success; - } - - void NetBindingSystemImpl::Reflect(AZ::ReflectContext* context) - { - if (context) - { - // We need to register the chunk type, and this would be a good time to do so. - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(NetBindingSystemContextData::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } -} // namespace AzFramework diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h b/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h deleted file mode 100644 index 543d9544ce..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetBindingSystemImpl.h +++ /dev/null @@ -1,311 +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 -#include -#include -#include -#include -#include -#include - -namespace AzFramework -{ - /** - * \brief Represents a request to bind a particular replica to an entity - */ - class BindRequest - { - public: - BindRequest() - : m_bindTo(GridMate::InvalidReplicaId) - , m_state(State::None) - { - } - - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_desiredRuntimeEntityId; - AZ::EntityId m_actualRuntimeEntityId; - AZStd::chrono::system_clock::time_point m_requestTime; - - /** - * \brief Represents the state of this bind request and it's relation to the slice instantiation process - */ - enum class State : AZ::u8 - { - None, - /** - * \brief This is the first request that led to instantiating a slice - */ - FirstBindInSlice, - /** - * \brief The request is a placeholder in case a real bind request arrives later. - * Some part of the slice may never be bound (e.g. if a replica is omitted by Interest Manager) - */ - PlaceholderBind, - /** - * \brief The real request did arrive to replace a placeholder request. - */ - LateBind, - }; - - State m_state; - }; - - typedef AZStd::unordered_map BindRequestContainerType; - - /** - * \brief Represents a slice instance being instantiated and bound to replicas - * \note It's possible that only some of the entities are activated and bound to replicas. - */ - class NetBindingSliceInstantiationHandler - : public SliceInstantiationResultBus::Handler - { - public: - ~NetBindingSliceInstantiationHandler() override; - - void InstantiateEntities(); - bool IsInstantiated() const; - bool IsANewSliceRequest() const; - bool IsBindingComplete() const; - - /** - * \note Returns false if there are no entities in the slice or the slice instance isn't ready yet. - * \return true if any of the entities from the slice are active - */ - bool HasActiveEntities() const; - - ////////////////////////////////////////////////////////////////////////// - // SliceInstantiationResultBus - void OnSlicePreInstantiate(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiated(const AZ::Data::AssetId& sliceAssetId, const AZ::SliceComponent::SliceInstanceAddress& sliceAddress) override; - void OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAssetId) override; - ////////////////////////////////////////////////////////////////////////// - - void InstantiationFailureCleanup(); - void UseCacheFor(BindRequest& request, const AZ::EntityId& staticEntityId); - void CloseEntityMap(const AZ::SliceComponent::EntityIdToEntityIdMap& staticToRuntimeMap); - - AZ::Data::AssetId m_sliceAssetId; - BindRequestContainerType m_bindingQueue; - SliceInstantiationTicket m_ticket; - - /** - * \breif a cache of entities that might be networked at some point - * \note they might be bound and unbound if their replicas leave and come back in the view - */ - AZStd::vector m_boundEntities; - - /** - * \brief identifies which slice instance the instantiation will be performed for - */ - AZ::SliceComponent::SliceInstanceId m_sliceInstanceId; - /** - * \brief when was the request to spawn a slice and bind it made - */ - AZStd::chrono::system_clock::time_point m_bindTime; - - AZ::SliceComponent::EntityIdToEntityIdMap m_staticToRuntimeEntityMap; - - /** - * \brief The state of the slice instance. - */ - enum class State - { - /** - * \brief Has not started instantiating the slice instance. - */ - NewRequest, - /** - * \brief Waiting on the slice to spawn. - */ - Spawning, - /** - * \brief Successfully spawned the slice assets. - */ - Spawned, - /** - * \brief Failed to spawn the slice. - */ - Failed - }; - - State m_state = State::NewRequest; - }; - - /** - * NetBindingSystemImpl works in conjunction with NetBindingComponent and - * NetBindingComponentChunk to perform network binding for game entities. - * - * It is responsible for adding entity replicas to the network on the master side - * and servicing entity spawn requests from the network on the proxy side, as - * well as detecting network availability and triggering network binding/unbinding. - * - * The system is first activated on the host side when OnNetworkSessionActivated event - * is received, and NetBindingSystemContextData is created. - * The system becomes fully operational when the NetBindingSystemContextData is activated - * and bound to the system, and remains operational as long as the NetBindingSystemContextData - * remains valid. - * - * Level switching is tracked by a monotonically increasing context sequence number controlled - * by the host. Spawn and bind operations are deferred until the correct sequence number - * is reached. Spawning is always performed from the game thread. - */ - class NetBindingSystemImpl - : public NetBindingSystemBus::Handler - , public NetBindingSystemEventsBus::Handler - , public EntityContextEventBus::Handler - , public AZ::TickBus::Handler - { - friend class NetBindingSystemContextData; - - public: - NetBindingSystemImpl(); - ~NetBindingSystemImpl() override; - - static void Reflect(AZ::ReflectContext* context); - - virtual void Init(); - virtual void Shutdown(); - - static const AZStd::chrono::milliseconds s_sliceBindingTimeout; - - ////////////////////////////////////////////////////////////////////////// - // NetBindingSystemBus - bool ShouldBindToNetwork() override; - NetBindingContextSequence GetCurrentContextSequence() override; - void AddReplicaMaster(AZ::Entity* entity, GridMate::ReplicaPtr replica) override; - AZ::EntityId GetStaticIdFromEntityId(AZ::EntityId entity) override; - AZ::EntityId GetEntityIdFromStaticId(AZ::EntityId staticEntityId) override; - void SpawnEntityFromSlice(GridMate::ReplicaId bindTo, const NetBindingSliceContext& bindToContext) override; - void SpawnEntityFromStream(AZ::IO::GenericStream& spawnData, AZ::EntityId useEntityId, GridMate::ReplicaId bindTo, NetBindingContextSequence addToContext) override; - void OnNetworkSessionActivated(GridMate::GridSession* session) override; - void OnNetworkSessionDeactivated(GridMate::GridSession* session) override; - void UnbindGameEntity(AZ::EntityId entity, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // EntityContextEventBus::Handler - void OnEntityContextReset() override; - void OnEntityContextLoadedFromStream(const AZ::SliceComponent::EntityList& contextEntities) override; - ////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////// - // TickBus::Handler - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; - int GetTickOrder() override; - ////////////////////////////////////////////////////////////////////////// - - protected: - //! Called by the NetBindingContext chunk when it is activated - void OnContextDataActivated(GridMate::ReplicaChunkPtr contextData); - - //! Called by the NetBindingContext chunk when it is deactivated - void OnContextDataDeactivated(GridMate::ReplicaChunkPtr contextData); - - //! Update the current binding context sequence - virtual void UpdateContextSequence(); - - //! Process pending spawn requests - virtual void ProcessSpawnRequests(); - - //! Process pending bind requests - virtual void ProcessBindRequests(); - - //! Performs final stage of entity spawning process - virtual bool BindAndActivate(AZ::Entity* entity, GridMate::ReplicaId replicaId, bool addToContext, const AZ::SliceComponent::SliceInstanceId& sliceInstanceId); - - //! Called on the host to spawn the net binding system replica - virtual GridMate::Replica* CreateSystemReplica(); - - AZ_FORCE_INLINE bool ReadyToAddReplica() const; - - class SpawnRequest - { - public: - GridMate::ReplicaId m_bindTo; - AZ::EntityId m_useEntityId; - AZStd::vector m_spawnDataBuffer; - }; - - typedef AZStd::list SpawnRequestContainerType; - typedef AZStd::map SpawnRequestContextContainerType; - - typedef AZStd::unordered_map SliceRequestContainerType; - typedef AZStd::map BindRequestContextContainerType; - - GridMate::GridSession* m_bindingSession; - GridMate::ReplicaChunkPtr m_contextData; - NetBindingContextSequence m_currentBindingContextSequence; - SpawnRequestContextContainerType m_spawnRequests; - BindRequestContextContainerType m_bindRequests; - AZStd::list> m_addMasterRequests; - - /** - * \brief override how root slice entities' replicas should be loaded - * - * We occasionally get GameContextBridge replica (that tells us what level to load) before we get - * a replica that tells us that we are connecting to a network sessions, thus we may not figure out in time if we - * need to load the root slice entities with NetBindingComponent as master replicas or proxy replicas. - * This is a fix until proper order is established. - * - * \param isAuthoritative true if root slice entities with NetBindingComponents to be loaded authoritatively - */ - void OverrideRootSliceLoadMode(bool isAuthoritative) - { - m_isAuthoritativeRootSliceLoad = isAuthoritative; - m_overrideRootSliceLoadAuthoritative = true; - } - - private: - /** - * \brief True if the root slice is to be loaded authoritatively - */ - bool m_isAuthoritativeRootSliceLoad; - /** - * \brief True if root slice loading mode was overriden, otherwise the mode would be determined via m_bindingSession - */ - bool m_overrideRootSliceLoadAuthoritative; - /** - * \brief A helper method to figure the mode of loading root slice entities' replicas - * \return True if the root slice entities is to be loaded authoritatively - */ - bool IsAuthoritateLoad() const; - - void UpdateClock(float deltaTime); - AZStd::chrono::system_clock::time_point Now() const; - - AZStd::chrono::system_clock::time_point m_currentTime; - }; - - class NetBindingSystemContextData - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(NetBindingSystemContextData, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingSystemContextData"; } - - NetBindingSystemContextData(); - - bool IsReplicaMigratable() override { return true; } - bool IsBroadcast() override { return true; } - - void OnReplicaActivate(const GridMate::ReplicaContext& rc) override; - - void OnReplicaDeactivate(const GridMate::ReplicaContext& rc) override; - - GridMate::DataSet m_bindingContextSequence; - }; -} // namespace AzFramework - diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h b/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h deleted file mode 100644 index 788eacf8b5..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetSystemBus.h +++ /dev/null @@ -1,38 +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 - -namespace AzFramework -{ - class NetworkContext; - - /** - * The NetSystemRequestBus services requests for global networking systems in AzFramework - */ - class NetSystemRequests - : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - - NetSystemRequests() = default; - virtual ~NetSystemRequests() = default; - - virtual NetworkContext* GetNetworkContext() = 0; - }; - - using NetSystemRequestBus = AZ::EBus; -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp deleted file mode 100644 index 98ef897d29..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.cpp +++ /dev/null @@ -1,378 +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 -#include -#include - - -namespace AzFramework -{ - NetworkContext::DescBase::DescBase(const char* name, ptrdiff_t offset) - : m_name(name) - , m_offset(offset) - { - } - - NetworkContext::FieldDescBase::FieldDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_dataSetIdx(static_cast(-1)) - { - } - - NetworkContext::RpcDescBase::RpcDescBase(const char* name, ptrdiff_t offset) - : DescBase(name, offset) - , m_rpcIdx(static_cast(-1)) - { - } - - NetworkContext::CtorDataBase::CtorDataBase(const char* name) - : m_name(name) - { - } - - NetworkContext::ClassBuilder::ClassBuilder(NetworkContext* context, ClassDescPtr binding) - : m_binding(binding) - , m_context(context) - { - } - - NetworkContext::ClassBuilder::~ClassBuilder() - { - if (m_context->IsRemovingReflection()) - { - if (m_binding->UnregisterChunkType) - { - m_binding->UnregisterChunkType(); - } - } - else - { - if (m_binding->RegisterChunkType) - { - m_binding->RegisterChunkType(); - } - } - } - - NetworkContext::ClassDesc::ClassDesc(const char* name, const AZ::Uuid& typeId /* = AZ::Uuid() */) - : m_name(name) - , m_typeId(typeId) - { - } - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext - /////////////////////////////////////////////////////////////////////////// - NetworkContext::NetworkContext() - { - } - - NetworkContext::~NetworkContext() - { - } - - size_t NetworkContext::GetReflectedChunkSize(const AZ::Uuid& typeId) const - { - size_t totalSize = 0; - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - for (const auto& field : binding->m_chunkDesc.m_fields) - { - totalSize += field->GetDataSetSize(); - } - - for (const auto& rpc : binding->m_chunkDesc.m_rpcs) - { - totalSize += rpc->GetRpcSize(); - } - } - - return totalSize; - } - - bool NetworkContext::UsesSelfAsChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return !binding->m_chunkDesc.m_external && binding->m_chunkDesc.m_fields.size() > 0; - } - return false; - } - - bool NetworkContext::UsesExternalChunk(const AZ::Uuid& typeId) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - return binding->m_chunkDesc.m_external && (AZ::u32(binding->m_chunkDesc.m_chunkId) != 0); - } - return false; - } - - ReplicaChunkBase* NetworkContext::CreateReplicaChunk(const AZ::Uuid& typeId) - { - const auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ClassDescPtr binding = it->second; - if (binding->CreateReplicaChunk) - { - ReplicaChunkDescriptor* descriptor = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(binding->m_chunkDesc.m_chunkId); - AZ_Assert(descriptor, "NetworkContext cannot find replica chunk descriptor for %s. Did you remember to register the chunk type?", binding->m_name); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(descriptor); - ReplicaChunkBase* chunk = binding->CreateReplicaChunk(); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - chunk->Init(descriptor); - return chunk; - } - } - - /* - * Special case: empty declarations such as: - * - * static void Reflect() { - * .... - * NetworkContext->Class(); - * } - * - * Result in no ReplicaChunks being created. It's treated as a no-op. No replication will be performed. - */ - return nullptr; - } - - void NetworkContext::DestroyReplicaChunk(ReplicaChunkBase* chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - ClassDescPtr binding = it->second; - binding->DestroyReplicaChunk(chunk); - return; - } - - AZ_Warning("NetworkContext", false, "DestroyReplicaChunk could not find a binding for %s", chunk->GetDescriptor()->GetChunkName()); - } - - void NetworkContext::Bind(NetBindable* instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode) - { - const AZ::Uuid& typeId = instance->RTTI_GetType(); - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - ClassDescPtr binding = it->second; - if (chunk) - { - ReplicaChunkClassId chunkId = chunk->GetDescriptor()->GetChunkTypeId(); - AZ_Assert(binding->m_chunkDesc.m_chunkId == chunkId, "NetworkContext detected a type mismatch while trying to bind an instance to a ReplicaChunk"); - if (binding->m_chunkDesc.m_chunkId == chunkId) - { - if (!binding->m_chunkDesc.m_external) - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk.get()); - refChunk->Bind(instance, mode); - } - } - } - else - { - if (binding->BindRpcs) - { - binding->BindRpcs(instance); - } - } - } - } - - void NetworkContext::EnumerateFields(const ReplicaChunkClassId& chunkId, FieldVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateFields(const AZ::Uuid& typeId, FieldVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& field : chunkDesc.m_fields) - { - visitor(field.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const ReplicaChunkClassId& chunkId, RpcVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateRpcs(const AZ::Uuid& typeId, RpcVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& rpc : chunkDesc.m_rpcs) - { - visitor(rpc.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const ReplicaChunkClassId& chunkId, CtorVisitor visitor) const - { - auto it = m_chunkBindings.find(chunkId); - if (it != m_chunkBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - void NetworkContext::EnumerateCtorData(const AZ::Uuid& typeId, CtorVisitor visitor) const - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - const ChunkDesc& chunkDesc = it->second->m_chunkDesc; - for (const auto& ctor : chunkDesc.m_ctors) - { - visitor(ctor.get()); - } - } - } - - /////////////////////////////////////////////////////////////////////////// - ReflectedReplicaChunkBase::ReflectedReplicaChunkBase() - : m_ctorBuffer(GridMate::EndianType::IgnoreEndian, 0) - { - } - - /////////////////////////////////////////////////////////////////////////// - NetworkContextChunkDescriptor::NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId) - : ReplicaChunkDescriptor(name, size) - , m_typeId(typeId) - { - } - - ReplicaChunkBase* NetworkContextChunkDescriptor::CreateFromStream(UnmarshalContext& ctx) - { - AZ_Assert(!m_typeId.IsNull(), "No typeid associated with NetworkContextChunkDescriptor, cannot spawn Chunk"); - if (!m_typeId.IsNull()) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to construct ReflectedReplicaChunk"); - - ReplicaChunkBase* replicaChunk = netContext->CreateReplicaChunk(m_typeId); - if (ctx.m_hasCtorData && ctx.m_iBuf) - { - NetworkContextChunkDescriptor* netChunkDesc = static_cast(replicaChunk->GetDescriptor()); - if (netChunkDesc->IsAuto()) - { - // copy each ctor data field into the ctor buffer - ReflectedReplicaChunkBase* refChunk = static_cast(replicaChunk); - netContext->EnumerateCtorData(m_typeId, - [&ctx, refChunk](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(*ctx.m_iBuf, refChunk->m_ctorBuffer); - }); - } - } - return replicaChunk; - } - return nullptr; - } - - void NetworkContextChunkDescriptor::DeleteReplicaChunk(ReplicaChunkBase* chunk) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to destroy ReflectedReplicaChunk"); - netContext->DestroyReplicaChunk(chunk); - } - - void NetworkContextChunkDescriptor::MarshalCtorData(ReplicaChunkBase* chunk, WriteBuffer& buffer) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to collect ctor data for ReflectedReplicaChunk"); - NetBindable* netBindable = static_cast(chunk->GetHandler()); - NetworkContextChunkDescriptor* netChunkDesc = static_cast(chunk->GetDescriptor()); - if (!netChunkDesc->IsAuto()) - { - return; - } - - if (netBindable) // chunk is bound, get source data from the netBindable - { - netContext->EnumerateCtorData(m_typeId, - [netBindable, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Marshal(netBindable, buffer); - }); - } - else // chunk is not bound yet, copy the ctor data for forwarding - { - ReflectedReplicaChunkBase* refChunk = static_cast(chunk); - ReadBuffer src(refChunk->m_ctorBuffer.GetEndianType(), refChunk->m_ctorBuffer.Get(), refChunk->m_ctorBuffer.Size()); - netContext->EnumerateCtorData(m_typeId, - [&src, &buffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Copy(src, buffer); - }); - } - } - - void NetworkContextChunkDescriptor::DiscardCtorStream(UnmarshalContext& ctx) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to skip ctor data for ReflectedReplicaChunk"); - if (ctx.m_hasCtorData) - { - // Iterate over all of the ctor data and unmarshal it with no destination, - // which will advance the buffer past the ctor data for this object - netContext->EnumerateCtorData(m_typeId, - [&ctx](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(*ctx.m_iBuf, nullptr); - }); - } - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h b/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h deleted file mode 100644 index 5b6d420a79..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Network/NetworkContext.h +++ /dev/null @@ -1,969 +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 -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class NetBindable; - - using GridMate::ReplicaChunkInterface; - using GridMate::ReplicaChunkBase; - using GridMate::ReplicaChunk; - using GridMate::ReplicaChunkDescriptor; - using GridMate::DefaultReplicaChunkDescriptor; - using GridMate::ReplicaChunkDescriptorTable; - using GridMate::ReplicaChunkClassId; - using GridMate::ReplicaChunkPtr; - using GridMate::Rpc; - using GridMate::ZoneMask; - using GridMate::ZoneMask_All; - using GridMate::UnmarshalContext; - using GridMate::ReadBuffer; - using GridMate::WriteBuffer; - using GridMate::WriteBufferDynamic; - - /////////////////////////////////////////////////////////////////////////// - // GridMate ReplicaChunk/ReplicaChunkDescriptors - /////////////////////////////////////////////////////////////////////////// - class ReflectedReplicaChunkBase - : public ReplicaChunkBase - , public ReplicaChunkInterface - { - friend NetworkContext; - public: - ReflectedReplicaChunkBase(); - bool IsReplicaMigratable() override { return true; } - - /// Returns the chunk type name, e.g. "ReflectedReplicaChunk" - virtual const char* GetName() const = 0; - /// Returns the linear size of the chunk including DataSets and RPCs - virtual size_t GetSize() const = 0; - /// Returns a pointer to the start of the DataSet/RPC storage allocated with the chunk - virtual AZ::u8* GetDataStart() const = 0; - /// Binds an instance of the reflected class to this chunk - virtual void Bind(NetBindable* instance, NetworkContextBindMode mode) = 0; - /// Removes network bindings from the bound NetBindable - virtual void Unbind() = 0; - - WriteBufferDynamic m_ctorBuffer; ///< Buffer to hold ctor data before the chunk is bound - }; - - /// This will be the header for a blob in memory: - /// The layout looks like: - /// * ReflectedReplicaChunk - /// * DataSets - /// * RPCs - template - class ReflectedReplicaChunk - : public ReflectedReplicaChunkBase - { - friend NetworkContext; - public: - static const char* GetChunkName(); - static size_t GetChunkSize(); - - public: - AZ_CLASS_ALLOCATOR(ReflectedReplicaChunk, AZ::SystemAllocator, 0); - ReflectedReplicaChunk() - : m_dataSets(reinterpret_cast(this) + sizeof(*this)) - { - } - - const char* GetName() const override { return GetChunkName(); } - size_t GetSize() const override { return GetChunkSize(); } - AZ::u8* GetDataStart() const override { return const_cast(m_dataSets); } - void Bind(NetBindable* instance, NetworkContextBindMode mode) override; - void Unbind() override; - - private: - const AZ::u8* m_dataSets; ///< Points to the beginning of the datasets for this chunk - }; - - class NetworkContextChunkDescriptor - : public ReplicaChunkDescriptor - { - public: - NetworkContextChunkDescriptor(const char* name, size_t size, const AZ::Uuid& typeId = AZ::Uuid()); - - ReplicaChunkBase* CreateFromStream(UnmarshalContext& ctx) override; - void DeleteReplicaChunk(ReplicaChunkBase* chunkInstance) override; - void DiscardCtorStream(UnmarshalContext&) override; - void MarshalCtorData(ReplicaChunkBase*, WriteBuffer&) override; - - void Bind(const AZ::Uuid& typeId) { m_typeId = typeId; } - virtual bool IsAuto() const { return false; } - - private: - AZ::Uuid m_typeId; ///< TypeId of the class this descriptor represents (not the chunk type) - }; - - template - class AutoChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - AutoChunkDescriptor() - : NetworkContextChunkDescriptor(ReflectedReplicaChunk::GetChunkName(), ReflectedReplicaChunk::GetChunkSize(), AZ::RttiTypeId()) - { - } - - ZoneMask GetZoneMask() const override { return mask; } - - bool IsAuto() const override { return true; } - }; - - template - class ExternalChunkDescriptor - : public NetworkContextChunkDescriptor - { - public: - ExternalChunkDescriptor() - : NetworkContextChunkDescriptor(ChunkType::GetChunkName(), sizeof(ChunkType)) - {} - - ZoneMask GetZoneMask() const override { return mask; } - }; - - /////////////////////////////////////////////////////////////////////////// - /// NetworkContext can be used to reflect classes for network serialization - /// It will automatically generate ReplicaChunks and bind them to instances - /// when requested. It also serves as a binding registry for binding a class - /// to the ReplicaChunk that should be used to replicate it. - /////////////////////////////////////////////////////////////////////////// - class NetworkContext - : public AZ::ReflectContext - { - public: - /// @cond EXCLUDE_DOCS - class ClassBuilder; - class ClassDesc; - using ClassDescPtr = AZStd::intrusive_ptr; - using ClassBuilderPtr = AZStd::intrusive_ptr; - using ClassBindings = AZStd::unordered_map; - using ChunkBindings = AZStd::unordered_map; - using ClassInfo = ClassBuilder; ///< @deprecated Use NetworkContext::ClassBuilder - using ClassInfoPtr = ClassBuilderPtr; ///< @deprecated Use NetworkContext::ClassBuilderPtr - /// @endcond - - class IntrusiveRefCounted - { - public: - virtual ~IntrusiveRefCounted() {} - private: - // refcount - template - friend struct AZStd::IntrusivePtrCountPolicy; - mutable unsigned int m_refCount = 0; - AZ_FORCE_INLINE void add_ref() { ++m_refCount; } - AZ_FORCE_INLINE void release() - { - AZ_Assert(m_refCount > 0, "Reference count logic error, trying to remove reference when refcount is 0"); - if (--m_refCount == 0) - { - delete this; - } - } - }; - - /** - * Interface for recording classes, chunks, and datasets - * When destructed at the end of reflection, it will register/unregister the ChunkDescriptor - */ - class ClassBuilder - : public IntrusiveRefCounted - { - friend class NetworkContext; - - protected: - AZ_CLASS_ALLOCATOR(ClassBuilder, AZ::SystemAllocator, 0); - ClassBuilder(NetworkContext* context, ClassDescPtr binding); - - public: - ~ClassBuilder(); - ClassBuilderPtr operator->() { return this; } - - /// Bind a ReplicaChunk type to this class for network serialization - template > - ClassBuilderPtr Chunk(); - - /// Bind a NetBindable's Field - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, FieldType ClassType::* address); - - /// Declare an external chunk's DataSet - template - typename AZStd::enable_if::value, ClassBuilderPtr>::type - Field(const char* name, DataSetType ClassType::* address); - - /// Bind an Rpc::BindInterface for this chunk - template ::template BindInterface > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - - /// Bind a NetBindable::Rpc for this NetBindable - template ::template Bind > - typename AZStd::enable_if::value, ClassBuilderPtr>::type - RPC(const char* name, RpcBindType ClassType::* rpc); - -#define CTOR_DATA_OVERLOAD(_getsig, _setsig) \ - template > \ - ClassBuilderPtr CtorData(const char* name, _getsig, _setsig, const MarshalerType&marshaler = MarshalerType()) \ - { \ - return CtorDataImpl(name, getter, setter, marshaler); \ - } - - /// Bind a getter/setter pair for data required during object construction - // this has to be done via overload so that the user does not have to explicitly provide - // the template arguments, they can be divined from the function call - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(const DataType&)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(DataType & (ClassType::* getter)() const, void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)(), void (ClassType::* setter)(DataType)); - CTOR_DATA_OVERLOAD(const DataType&(ClassType::* getter)() const, void (ClassType::* setter)(DataType)); -#undef CTOR_DATA_OVERLOAD - - private: - template > - ClassBuilderPtr CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType& marshaler = MarshalerType()); - - private: - ClassDescPtr m_binding; - NetworkContext* m_context; - }; - - class DescBase - : public IntrusiveRefCounted - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(DescBase, AZ::SystemAllocator, 0); - DescBase(const char* name, ptrdiff_t offset); - virtual ~DescBase() {} - - const char* GetName() const { return m_name; } - ptrdiff_t GetOffset() const { return m_offset; } - protected: - const char* m_name; ///< Field name, will be used as DataSet debug name - ptrdiff_t m_offset; ///< Offset from an instance pointer (a ReplicaChunk or the actual class instance) - }; - - class FieldDescBase - : public DescBase - { - friend class NetworkContext; - - public: - AZ_CLASS_ALLOCATOR(FieldDescBase, AZ::SystemAllocator, 0); - FieldDescBase(const char* name, ptrdiff_t offset); - virtual ~FieldDescBase() {} - - virtual void ConstructDataSet(void*) const = 0; - virtual void DestructDataSet(void*) const = 0; - virtual size_t GetDataSetSize() const = 0; - - size_t GetDataSetIndex() const { return m_dataSetIdx; } - - protected: - size_t m_dataSetIdx; - }; - - /** - * Represents a DataSet in a chunk or class - * NOTE: m_offset in this class is the offset from ReplicaChunk* -> DataSet - */ - template - class DataSetDesc - : public FieldDescBase - { - public: - AZ_CLASS_ALLOCATOR(DataSetDesc, AZ::SystemAllocator, 0); - DataSetDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void*) const override {} - void DestructDataSet(void*) const override {} - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - /** - * Represents a field in a chunk, responsible for creating a DataSet - * that represents the field - * NOTE: m_offset in this class is the offset from NetBindable* -> NetBindable::Field - */ - template - class NetBindableFieldDesc - : public FieldDescBase - { - public: - using DataSetType = typename FieldType::DataSetType; - - public: - AZ_CLASS_ALLOCATOR(NetBindableFieldDesc, AZ::SystemAllocator, 0); - NetBindableFieldDesc(const char* name, ptrdiff_t offset); - - void ConstructDataSet(void* mem) const override { FieldType::ConstructDataSet(mem, m_name); } - void DestructDataSet(void* mem) const override { FieldType::DestructDataSet(mem); } - size_t GetDataSetSize() const override { return sizeof(DataSetType); } - }; - - class RpcDescBase - : public DescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(RpcDescBase, AZ::SystemAllocator, 0); - RpcDescBase(const char* name, ptrdiff_t offset); - virtual ~RpcDescBase() {} - - virtual void ConstructRpc(void*) const {} - virtual void DestructRpc(void*) const {} - virtual size_t GetRpcSize() const { return 0; } - - size_t GetRpcIndex() const { return m_rpcIdx; } - - protected: - size_t m_rpcIdx; - }; - - template - class NetBindableRpcDesc - : public RpcDescBase - { - friend class NetworkContext; - public: - AZ_CLASS_ALLOCATOR(NetBindableRpcDesc, AZ::SystemAllocator, 0); - NetBindableRpcDesc(const char* name, ptrdiff_t offset) - : RpcDescBase(name, offset) - { - static_assert((AZStd::is_base_of::value), "NetBindableRpcDesc is intended for use only with NetBindableRpcs"); - } - - void ConstructRpc(void* mem) const override { RpcBindType::ConstructRpc(mem, m_name); } - void DestructRpc(void* mem) const override { RpcBindType::DestructRpc(mem); } - size_t GetRpcSize() const override { return sizeof(typename RpcBindType::BindInterfaceType); } - }; - - class CtorDataBase - : public IntrusiveRefCounted - { - public: - AZ_CLASS_ALLOCATOR(CtorDataBase, AZ::SystemAllocator, 0); - CtorDataBase(const char* name); - virtual ~CtorDataBase() {} - - virtual void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const = 0; - virtual void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const = 0; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const = 0; - - protected: - const char* m_name; - }; - - template - class CtorDataDesc - : public CtorDataBase - { - using GetterFunction = AZStd::function; - using SetterFunction = AZStd::function; - public: - AZ_CLASS_ALLOCATOR(CtorDataDesc, AZ::SystemAllocator, 0); - CtorDataDesc(const char* name, GetterFunction get, SetterFunction set) - : CtorDataBase(name) - , m_get(get) - , m_set(set) - {} - - CtorDataDesc(const char* name, DataType(ClassType::* getter)(), void (ClassType::* setter)(const DataType&)) - : CtorDataBase(name) - , m_get(AZStd::bind(getter, AZStd::placeholders::_1)) - , m_set(AZStd::bind(setter, AZStd::placeholders::_1, AZStd::placeholders::_2)) - {} - - void Marshal(NetBindable* netBindable, WriteBuffer& buffer) const override; - void Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const override; - virtual void Copy(ReadBuffer& src, WriteBuffer& dest) const override; - - GetterFunction m_get; - SetterFunction m_set; - MarshalerType m_marshaler; - }; - - struct ChunkDesc - { - public: - using Fields = AZStd::vector >; - using Rpcs = AZStd::vector >; - using Ctors = AZStd::vector >; - - const char* m_name = nullptr; ///< The name of the chunk - ReplicaChunkClassId m_chunkId; ///< The registered id of the ReplicaChunk this class will use - Fields m_fields; ///< list of data fields in the ReplicaChunk - Rpcs m_rpcs; ///< list of RPCs in the ReplicaChunk - Ctors m_ctors; ///< list of ctor callbacks to gather/apply ctor data - bool m_external = false; ///< If true, this chunk is separate from the class bound to it - }; - - /** - * Contains the chunk factory and field descriptions for a given class - */ - class ClassDesc - : public IntrusiveRefCounted - { - public: - - AZ_CLASS_ALLOCATOR(ClassDesc, AZ::SystemAllocator, 0); - ClassDesc(const char* name = nullptr, const AZ::Uuid& typeId = AZ::Uuid()); - - public: - const char* m_name; ///< The name of the class that is bound - AZ::Uuid m_typeId; ///< The type that this binding represents (null for chunks) - ChunkDesc m_chunkDesc; ///< Descriptor for the chunk for this type - - /// Functor which will register the ReplicaChunkDescriptor with the global registry - AZStd::function RegisterChunkType; - /// Functor to unregister the ReplicaChunkDescriptor (during reflection removal) - AZStd::function UnregisterChunkType; - /// Functor which will create a ReplicaChunk and bind it to the given instance - AZStd::function CreateReplicaChunk; - /// Functor which can destroy a ReplicaChunk and free its memory - AZStd::function DestroyReplicaChunk; - /// Functor which binds an instance of this class to its RPCs for local dispatch - AZStd::function BindRpcs; - }; - - AZ_CLASS_ALLOCATOR(NetworkContext, AZ::SystemAllocator, 0); - AZ_RTTI(NetworkContext, "{B1172D4A-EA1B-441D-AAE6-A9933DAECA8A}", AZ::ReflectContext); - - NetworkContext(); - virtual ~NetworkContext(); - - /// Register a class with the NetworkContext for replication - template - ClassBuilderPtr Class(); - - /// Create a replica chunk for a given class - ReplicaChunkBase* CreateReplicaChunk(const AZ::Uuid& typeId); - - /// Create a replica chunk for a given class, template version - template - ReplicaChunkBase* CreateReplicaChunk(); - - /// Destroy a replica chunk for a given class - void DestroyReplicaChunk(ReplicaChunkBase * chunk); - - /// Bind an instance and a chunk to each other - void Bind(NetBindable * instance, ReplicaChunkPtr chunk, NetworkContextBindMode mode); - - /// Returns whether or not a given type uses a reflected (automatic) ReplicaChunk - bool UsesSelfAsChunk(const AZ::Uuid & typeId) const; - - /// Returns whether or not a given type uses a custom ReplicaChunk - bool UsesExternalChunk(const AZ::Uuid & typeId) const; - - /// Return the size of the the chunk which will represent the given type - size_t GetReflectedChunkSize(const AZ::Uuid & typeId) const; - - using FieldVisitor = AZStd::function; - void EnumerateFields(const ReplicaChunkClassId&chunkId, FieldVisitor visitor) const; - void EnumerateFields(const AZ::Uuid & typeId, FieldVisitor visitor) const; - - using RpcVisitor = AZStd::function; - void EnumerateRpcs(const ReplicaChunkClassId&chunkId, RpcVisitor visitor) const; - void EnumerateRpcs(const AZ::Uuid & typeId, RpcVisitor visitor) const; - - using CtorVisitor = AZStd::function; - void EnumerateCtorData(const ReplicaChunkClassId&chunkId, CtorVisitor visitor) const; - void EnumerateCtorData(const AZ::Uuid & typeId, CtorVisitor visitor) const; - - private: - template - void InitReflectedChunkBinding(ClassDescPtr binding); - - template > - void InitExternalChunkBinding(ClassDescPtr binding); - - private: - ClassBindings m_classBindings; - ChunkBindings m_chunkBindings; - }; - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::Class() - { - static_assert((AZStd::is_base_of::value), "Classes reflected through NetworkContext must be derived from NetBindable"); - const AZ::Uuid& typeId = AZ::AzTypeInfo::Uuid(); - ClassDescPtr binding = nullptr; - if (IsRemovingReflection()) // Just remove the entire class definition - { - auto it = m_classBindings.find(typeId); - if (it != m_classBindings.end()) - { - binding = it->second; - m_chunkBindings.erase(binding->m_chunkDesc.m_chunkId); - m_classBindings.erase(it); - } - } - else - { - auto ret = m_classBindings.insert_key(typeId); - AZ_Assert(ret.second, "Cannot register more than one type with the same Uuid in the NetworkContext"); - binding = ret.first->second = aznew ClassDesc(AZ::AzTypeInfo::Name(), AZ::AzTypeInfo::Uuid()); - } - - return aznew ClassBuilder(this, binding); - } - - template - void NetworkContext::InitReflectedChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ReflectedReplicaChunk::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - NetworkContext* netContext = this; - - binding->RegisterChunkType = [chunkClassId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType, AutoChunkDescriptor >(); - ReplicaChunkDescriptor* desc = ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId); - ReplicaChunkDescriptorTable::Get().BeginConstructReplicaChunk(desc); - // The offset recorded in NetBindableFields is the offset in the NetBindable - // We must compute the offset of the generated DataSets here and record the - // index from the descriptor - ptrdiff_t offset = sizeof(ReflectedReplicaChunk); // data sets are right after the ReflectedReplicaChunk<> in memory - netContext->EnumerateFields(chunkClassId, - [desc, &offset](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, offset); - field->m_dataSetIdx = desc->GetDataSetIndex(offset); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc, &offset](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, offset); - rpc->m_rpcIdx = desc->GetRpcIndex(offset); - offset += rpc->GetRpcSize(); - }); - AZ_Assert(offset == static_cast(ReflectedReplicaChunk::GetChunkSize()), "Overflow/underflow while registering DataSets for %s", ReflectedReplicaChunk::GetChunkName()); - ReplicaChunkDescriptorTable::Get().EndConstructReplicaChunk(); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = [netContext, chunkClassId]() - { - ReflectedReplicaChunkBase* chunk = new(azmalloc(ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkName()))ReflectedReplicaChunk(); - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->ConstructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->ConstructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - return chunk; - }; - - binding->DestroyReplicaChunk = [netContext, chunkClassId](ReplicaChunkBase* chunkBase) - { - AZ_Assert(chunkBase->GetDescriptor()->GetChunkTypeId() == chunkClassId, "Mismatched chunk type id for %s (0x%p)", ReflectedReplicaChunk::GetChunkName(), chunkBase); - ReflectedReplicaChunkBase* chunk = static_cast(chunkBase); - chunk->Unbind(); - - AZ::u8* dataStart = chunk->GetDataStart(); - AZ::u8* dataEnd = reinterpret_cast(chunk) + chunk->GetSize(); - ptrdiff_t offset = 0; - netContext->EnumerateFields(chunkClassId, - [&offset, dataStart, dataEnd](FieldDescBase* field) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - void* dataSetMem = reinterpret_cast(dataStart + offset); - field->DestructDataSet(dataSetMem); - offset += field->GetDataSetSize(); - }); - netContext->EnumerateRpcs(chunkClassId, - [&offset, dataStart, dataEnd](RpcDescBase* rpc) - { - AZ_Assert((dataStart + offset) < dataEnd, "Overflow in NetworkContext::CreateReplicaChunk while creating %s", ReflectedReplicaChunk::GetChunkName()); - void* rpcMem = reinterpret_cast(dataStart + offset); - rpc->DestructRpc(rpcMem); - offset += rpc->GetRpcSize(); - }); - AZ_Assert((dataStart + offset) == dataEnd, "Overflow/underflow in dtor while destroying %s", ReflectedReplicaChunk::GetChunkName()); - chunk->~ReflectedReplicaChunkBase(); - azfree(chunk, AZ::SystemAllocator, ReflectedReplicaChunk::GetChunkSize(), AZStd::alignment_of >::value); - }; - - binding->BindRpcs = [netContext, chunkClassId](NetBindable* bindable) - { - ClassType* derivedInstance = static_cast(bindable); - netContext->EnumerateRpcs(chunkClassId, - [derivedInstance](const RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - void NetworkContext::InitExternalChunkBinding(ClassDescPtr binding) - { - if (!binding->RegisterChunkType) - { - binding->m_chunkDesc.m_name = ChunkType::GetChunkName(); - ReplicaChunkClassId chunkClassId = ReplicaChunkClassId(binding->m_chunkDesc.m_name); - m_chunkBindings[chunkClassId] = binding; - const AZ::Uuid& typeId = binding->m_typeId; - NetworkContext* netContext = this; - binding->RegisterChunkType = [chunkClassId, typeId, netContext]() - { - bool result = ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - NetworkContextChunkDescriptor* desc = static_cast(ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(chunkClassId)); - desc->Bind(typeId); - netContext->EnumerateFields(chunkClassId, - [desc](FieldDescBase* field) - { - desc->RegisterDataSet(field->m_name, field->m_offset); - field->m_dataSetIdx = desc->GetDataSetIndex(field->m_offset); - }); - netContext->EnumerateRpcs(chunkClassId, - [desc](RpcDescBase* rpc) - { - desc->RegisterRPC(rpc->m_name, rpc->m_offset); - }); - return result; - }; - - binding->UnregisterChunkType = [chunkClassId]() - { - return ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(chunkClassId); - }; - - binding->CreateReplicaChunk = []() - { - return aznew ChunkType(); - }; - - binding->DestroyReplicaChunk = [](ReplicaChunkBase* chunk) - { - delete chunk; - }; - - binding->m_chunkDesc.m_chunkId = chunkClassId; - } - } - - template - ReplicaChunkBase* NetworkContext::CreateReplicaChunk() - { - return CreateReplicaChunk(AZ::AzTypeInfo::Uuid()); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::DataSetDesc::DataSetDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::NetBindableFieldDesc::NetBindableFieldDesc(const char* name, ptrdiff_t offset) - : NetworkContext::FieldDescBase(name, offset) - { - } - - /////////////////////////////////////////////////////////////////////////// - template - void NetworkContext::CtorDataDesc::Marshal(NetBindable* netBindable, WriteBuffer& buffer) const - { - ClassType* instance = static_cast(netBindable); - DataType data = m_get(instance); - buffer.Write(data, m_marshaler); - } - - template - void NetworkContext::CtorDataDesc::Unmarshal(ReadBuffer& buffer, NetBindable* netBindable) const - { - ClassType* instance = static_cast(netBindable); - DataType data; - buffer.Read(data, m_marshaler); - if (instance) - { - m_set(instance, data); - } - } - - template - void NetworkContext::CtorDataDesc::Copy(ReadBuffer& src, WriteBuffer& dest) const - { - DataType data; - src.Read(data, m_marshaler); - dest.Write(data, m_marshaler); - } - - /////////////////////////////////////////////////////////////////////////// - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::Chunk() - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "ReplicaChunks being registered with the NetworkContext must derive from ReplicaChunk"); - static_assert((AZStd::is_base_of::value), "Chunk bindings via NetworkContext must use a NetworkContextChunkDescriptor derived descriptor"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a ReplicaChunk for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_chunkId, "Cannot register more than one ReplicaChunk binding for a class in the NetworkContext"); - - m_context->InitExternalChunkBinding(m_binding); - m_binding->m_chunkDesc.m_external = true; - } - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, FieldType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - AZ_Assert(!m_binding->m_chunkDesc.m_external, "Cannot register a NetBindable::Field from within an external chunk"); - - m_context->InitReflectedChunkBinding(m_binding); - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew NetBindableFieldDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::Field(const char* name, DataSetType ClassType::* address) - { - if (!m_context->IsRemovingReflection()) - { - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register a field for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*address)); - m_binding->m_chunkDesc.m_fields.push_back(aznew DataSetDesc(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew RpcDescBase(name, offset)); - } - - return this; - } - - template - typename AZStd::enable_if::value, NetworkContext::ClassBuilderPtr>::type - NetworkContext::ClassBuilder::RPC(const char* name, RpcBindType ClassType::* rpc) - { - if (!m_context->IsRemovingReflection()) - { - static_assert((AZStd::is_base_of::value), "Cannot bind an RPC call to an object which is not a ReplicaChunkInterface"); - AZ_Assert(!m_binding->m_typeId.IsNull(), "Cannot register an RPC for a class which has not been declared to the NetworkContext"); - - m_context->InitReflectedChunkBinding(m_binding); - - ptrdiff_t offset = reinterpret_cast(&(reinterpret_cast(0)->*rpc)); - m_binding->m_chunkDesc.m_rpcs.push_back(aznew NetBindableRpcDesc(name, offset)); - } - - return this; - } - - template - NetworkContext::ClassBuilderPtr NetworkContext::ClassBuilder::CtorDataImpl(const char* name, GetterFunction getter, SetterFunction setter, const MarshalerType&) - { - if (!m_context->IsRemovingReflection()) - { - m_context->InitReflectedChunkBinding(m_binding); - - auto get = [getter](NetBindable* nb) -> DataType { return (*static_cast(nb).*getter)(); }; - auto set = [setter](NetBindable* nb, const DataType& data) { (*static_cast(nb).*setter)(data); }; - m_binding->m_chunkDesc.m_ctors.push_back(aznew CtorDataDesc(name, get, set)); - } - - return this; - } - - /////////////////////////////////////////////////////////////////////////// - template - const char* ReflectedReplicaChunk::GetChunkName() - { - static char name[128] = { 0 }; - if (!name[0]) - { - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), "ReflectedReplicaChunk<"); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), AZ::AzTypeInfo::Name()); - AZ::Internal::AzTypeInfoSafeCat(name, AZ_ARRAY_SIZE(name), ">"); - } - return name; - } - - template - size_t ReflectedReplicaChunk::GetChunkSize() - { - static size_t chunkSize = 0; - if (chunkSize == 0) - { - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_Assert(netContext, "No NetworkContext found while trying to compute chunk size"); - if (!netContext) - { - return 0; - } - chunkSize = sizeof(ReflectedReplicaChunk) + netContext->GetReflectedChunkSize(AZ::AzTypeInfo::Uuid()); - } - - return chunkSize; - } - - template - void ReflectedReplicaChunk::Bind(NetBindable* instance, NetworkContextBindMode mode) - { - SetHandler(instance); - ClassType* derivedInstance = azrtti_cast(instance); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s", AZ::AzTypeInfo::Name()); - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [this, derivedInstance, desc, mode](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - DataSetBase* dataSet = desc->GetDataSet(this, field->GetDataSetIndex()); - bindableField->Bind(dataSet, mode); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [this, derivedInstance, desc](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - RpcBase* rpcBase = desc->GetRpc(this, rpc->GetRpcIndex()); - bindableRpc->Bind(rpcBase); - }); - - // Transfer any stored ctor data from the buffer -> NetBindable instance - if (m_ctorBuffer.Size() > 0) - { - ReadBuffer ctorBuffer(m_ctorBuffer.GetEndianType(), m_ctorBuffer.Get(), m_ctorBuffer.Size()); - netContext->EnumerateCtorData(desc->GetChunkTypeId(), - [instance, &ctorBuffer](NetworkContext::CtorDataBase* ctorData) - { - ctorData->Unmarshal(ctorBuffer, instance); - }); - } - } - - template - void ReflectedReplicaChunk::Unbind() - { - ReplicaChunkInterface* handler = GetHandler(); - if (!handler || handler == this) - { - return; - } - - NetBindable* netBindable = static_cast(handler); - ClassType* derivedInstance = azrtti_cast(netBindable); - AZ_Assert(derivedInstance, "Unable to convert NetBindable to %s. Have you forgotten to derive your component from AzFramework::NetBindable?", AZ::AzTypeInfo::Name()); - if (derivedInstance) - { - ReplicaChunkDescriptor* desc = GetDescriptor(); - NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - netContext->EnumerateFields(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::FieldDescBase* field) - { - NetBindableFieldBase* bindableField = reinterpret_cast(reinterpret_cast(derivedInstance) + field->GetOffset()); - bindableField->Bind(nullptr, NetworkContextBindMode::NonAuthoritative); - }); - netContext->EnumerateRpcs(desc->GetChunkTypeId(), - [derivedInstance](NetworkContext::RpcDescBase* rpc) - { - NetBindableRpcBase* bindableRpc = reinterpret_cast(reinterpret_cast(derivedInstance) + rpc->GetOffset()); - bindableRpc->Bind(derivedInstance); - }); - } - - // We have disconnected from the handler and erased any connections from DataFields or Rpcs - SetHandler(nullptr); - } -} // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h index 60da2c3607..f96af2bcf9 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/WindBus.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace Physics diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp index 838ab0b6e2..30343b1322 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.cpp @@ -26,12 +26,9 @@ #include #include -#include -#include #include -#include #include @@ -429,83 +426,60 @@ namespace AzFramework { LSV_BEGIN(lua, 1); - // calling format __index(table,key) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); + AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, + "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); + int lookupKey = lua_gettop(lua); - bool readValue = false; - - if (netBindingTable != nullptr) + int lookupTable = lookupKey - 1; + // This is a slow function and it's made slow so we don't cache any extra data. + // This is done because this function will be called only the exported components + // and script are not in sync and we added new properties. + lua_getmetatable(lua, -2); // get the metatable which will be the top property table + int entityProperties = lua_gettop(lua); + if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table { - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptComponent",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - readValue = netBindingTable->InspectTableValue(stackContext); - } + // we are looking at top level properties + lua_pushvalue(lua, -2); // copy the key + lua_rawget(lua, -2); // read the value } - - if (!readValue) + else { - AZ::ScriptContext::FromNativeContext(lua)->Error(AZ::ScriptContext::ErrorType::Warning, true, - "Property %s not found in entity table. Please push this property to your slice to avoid decrease in performance.", lua_tostring(lua, -1)); - int lookupKey = lua_gettop(lua); - - int lookupTable = lookupKey - 1; - // This is a slow function and it's made slow so we don't cache any extra data. - // This is done because this function will be called only the exported components - // and script are not in sync and we added new properties. - lua_getmetatable(lua, -2); // get the metatable which will be the top property table - int entityProperties = lua_gettop(lua); - if (lua_getmetatable(lua, -1) == 0) // get the metatable of the property which will be the original table + // we are looking into the sub table, so do a slow traversal + int scriptProperties = lua_gettop(lua); + if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) { - // we are looking at top level properties - lua_pushvalue(lua, -2); // copy the key - lua_rawget(lua, -2); // read the value + lua_pushnil(lua); + return 1; // we did not find the table } else { - // we are looking into the sub table, so do a slow traversal - int scriptProperties = lua_gettop(lua); - if (!Properties__IndexFindSubtable(lua, lookupTable, entityProperties, scriptProperties)) - { - lua_pushnil(lua); - return 1; // we did not find the table - } - else - { - lua_pushvalue(lua, lookupKey); - lua_rawget(lua, -2); - } - } - - if (lua_istable(lua, -1)) - { - // if we are here the target table is on the top if the stack - lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_pushvalue(lua, lookupKey); lua_rawget(lua, -2); - if (lua_isnil(lua, -1)) - { - // parent table is a group, pop the value and return the table - lua_pop(lua, 1); - } } - - // Duplicate the value, so once the storage is done its on top of the stack, and returned - lua_pushvalue(lua, -1); - - // Push key, and then move it below the value - lua_pushvalue(lua, lookupKey); - lua_insert(lua, -2); - - // Cache the value so that subsequent accesses to this property don't result in warnings - lua_rawset(lua, lookupTable); } + + if (lua_istable(lua, -1)) + { + // if we are here the target table is on the top if the stack + lua_pushstring(lua, ScriptComponent::DefaultFieldName); + lua_rawget(lua, -2); + if (lua_isnil(lua, -1)) + { + // parent table is a group, pop the value and return the table + lua_pop(lua, 1); + } + } + + // Duplicate the value, so once the storage is done its on top of the stack, and returned + lua_pushvalue(lua, -1); + + // Push key, and then move it below the value + lua_pushvalue(lua, lookupKey); + lua_insert(lua, -2); + + // Cache the value so that subsequent accesses to this property don't result in warnings + lua_rawset(lua, lookupTable); + return 1; } //========================================================================= @@ -515,30 +489,7 @@ namespace AzFramework { LSV_BEGIN_VARIABLE(lua); - // calling format __newindex(table,key,value) - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua, lua_upvalueindex(1))); - if (netBindingTable != nullptr) - { - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() != nullptr,"ScriptNetBindingTable is missing ScriptContext."); - AZ_Error("ScriptContext",netBindingTable->GetScriptContext() == nullptr || netBindingTable->GetScriptContext()->NativeContext() == lua,"Trying to use a NetBindingTable in wrong lua context"); - - AZ::ScriptContext* scriptContext = netBindingTable->GetScriptContext(); - if (scriptContext) - { - AZ::ScriptDataContext stackContext; - scriptContext->ReadStack(stackContext); - - const bool assignedValue = netBindingTable->AssignTableValue(stackContext); - if (assignedValue) - { - LSV_END_VARIABLE(0); - return 0; - } - } - } - - // If we didn't assign the value above, we want - // to raw set the value to avoid coming back in here. + // We want to raw set the value to avoid coming back in here. lua_rawset(lua, 1); LSV_END_VARIABLE(-2); return 0; @@ -553,7 +504,6 @@ namespace AzFramework // [8/9/2013] //========================================================================= - const char* ScriptComponent::NetRPCFieldName = "NetRPCs"; const char* ScriptComponent::DefaultFieldName = "default"; ScriptComponent::ScriptComponent() @@ -561,7 +511,6 @@ namespace AzFramework , m_contextId(AZ::ScriptContextIds::DefaultScriptContextId) , m_script(AZ::Data::AssetLoadBehavior::PreLoad) , m_table(LUA_NOREF) - , m_netBindingTable(nullptr) { m_properties.m_name = "Properties"; } @@ -573,8 +522,6 @@ namespace AzFramework ScriptComponent::~ScriptComponent() { m_properties.Clear(); - - delete m_netBindingTable; } //========================================================================= @@ -604,11 +551,6 @@ namespace AzFramework return m_properties.GetProperty(propertyName); } - const AZ::ScriptProperty* ScriptComponent::GetNetworkedScriptProperty(const char* propertyName) const - { - return m_netBindingTable->FindScriptProperty(propertyName); - } - void ScriptComponent::Init() { // Grab the script context @@ -622,11 +564,6 @@ namespace AzFramework //========================================================================= void ScriptComponent::Activate() { - if (m_isSyncEnabled && m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - // if we have valid asset listen for script asset events, like reload if (m_script.GetId().IsValid()) { @@ -681,43 +618,6 @@ namespace AzFramework LoadScript(); } - //========================================================================= - // ScriptComponent::GetNetworkBinding - //========================================================================= - GridMate::ReplicaChunkPtr ScriptComponent::GetNetworkBinding() - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - return m_netBindingTable->GetNetworkBinding(); - } - - //========================================================================= - // ScriptComponent::SetNetworkBinding - //========================================================================= - void ScriptComponent::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - if (m_netBindingTable == nullptr) - { - m_netBindingTable = aznew ScriptNetBindingTable(); - } - - m_netBindingTable->SetNetworkBinding(chunk); - } - - //========================================================================= - // ScriptComponent::UnbindFromNetwork - //========================================================================= - void ScriptComponent::UnbindFromNetwork() - { - if (m_netBindingTable) - { - m_netBindingTable->UnbindFromNetwork(); - } - } - //========================================================================= // LoadScript //========================================================================= @@ -741,11 +641,6 @@ namespace AzFramework AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::Script, "Unload: %s", m_script.GetHint().c_str()); DestroyEntityTable(); - - if (m_netBindingTable) - { - m_netBindingTable->Unload(); - } } //========================================================================= @@ -798,12 +693,10 @@ namespace AzFramework // set the __index so we can read values in case we change the script // after we export the component lua_pushliteral(lua, "__index"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__Index, 1); lua_rawset(lua, -3); lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); } @@ -835,8 +728,7 @@ namespace AzFramework { const char* tableName = lua_tolstring(lua, -2, nullptr); if (strncmp(tableName, "__", 2) == 0 || // skip metatables - strcmp(tableName, propertyTableName) == 0 || // Skip the Properties table - strcmp(tableName, ScriptComponent::NetRPCFieldName) == 0) // Want to skip the RPC table as well + strcmp(tableName, propertyTableName) == 0) // Skip the Properties table { break; } @@ -904,13 +796,10 @@ namespace AzFramework } lua_createtable(lua, 0, 1); // Create entity table; - int entityStackIndex = lua_gettop(lua); + [[maybe_unused]] int entityStackIndex = lua_gettop(lua); // Stack: ScriptRootTable PropertiesTable EntityTable - // Create our network binding. - CreateNetworkBindingTable(baseStackIndex, entityStackIndex); - if (basePropertyTable > -1) // if property table exists { CreatePropertyGroup(m_properties, basePropertyTable, lua_gettop(lua), basePropertyTable, true); @@ -932,11 +821,6 @@ namespace AzFramework // Keep the entity table in the registry m_table = luaL_ref(lua, LUA_REGISTRYINDEX); - if (m_netBindingTable) - { - m_netBindingTable->FinalizeNetworkTable(m_context, m_table); - } - // call OnActivate lua_pushliteral(lua, "OnActivate"); lua_rawget(lua, baseStackIndex); // ScriptTable[OnActivate] @@ -993,18 +877,6 @@ namespace AzFramework } } - //========================================================================= - // CreateNetworkBindingTable - // [6/27/2016] - //========================================================================= - void ScriptComponent::CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex) - { - if (m_netBindingTable) - { - m_netBindingTable->CreateNetworkBindingTable(m_context, baseStackIndex, entityStackIndex); - } - } - //========================================================================= // CreatePropertyGroup // [3/3/2014] @@ -1028,12 +900,10 @@ namespace AzFramework // Ensure that this instance of Properties table has the proper __index and __newIndex metamethods. lua_newtable(lua); // This new table will become the Properties instance metatable. Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} lua_pushliteral(lua, "__index"); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index - lua_pushlightuserdata(lua, m_netBindingTable); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index m_netBinding lua_pushcclosure(lua, &Internal::Properties__Index, 1); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {} __index function lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index} lua_pushliteral(lua, "__newindex"); - lua_pushlightuserdata(lua, m_netBindingTable); lua_pushcclosure(lua, &Internal::Properties__NewIndex, 1); lua_rawset(lua, -3); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {} {__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} lua_setmetatable(lua, -2); // Stack: ScriptRootTable PropertiesTable EntityTable "Properties" {Meta{__index=Internal::Properties__Index __newindex=Internal::Properties__NewIndex} } @@ -1050,55 +920,6 @@ namespace AzFramework { AZ::ScriptProperty* prop = group.m_properties[i]; - if (m_netBindingTable != nullptr) - { - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); - lua_rawget(lua, propertyGroupTableIndex); - - // Stack: ... SomePropertyInThePropertiesTable. This may be any basic lua type (number, string, table etc) - if (lua_istable(lua, -1)) - { - bool isNetworkedProperty = false; - - AZ::ScriptDataContext stackContext; - - // If we find a table value. We want to inspect it for information. - if (m_context->ReadStack(stackContext)) - { - // check if the current property, which is a table, has a sub-table called "netSynched" - lua_pushliteral(lua, "netSynched"); // Stack: ... SomePropertyInThePropertiesTable netSynched - lua_rawget(lua, -2); // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable/nil - if (stackContext.IsTable(-1)) - { - AZ::ScriptDataContext networkTableContext; - if (stackContext.InspectTable(-1, networkTableContext)) // Stack: ... SomePropertyInThePropertiesTable NetSynchedSubTable NetSynchedSubTable nil nil - { - // RegisterDataSet will make sure our __NewIndex function callback will be triggered whenever modifying netSynched Properties. - //isNetworkedProperty = true; - isNetworkedProperty = m_netBindingTable->RegisterDataSet(networkTableContext, prop); - } - } - - // Network binding table - lua_pop(lua, 1); // Stack: ... SomePropertyInThePropertiesTable - } - - // Pop this PropertiesTable's property - lua_pop(lua, 1); - - // If the property is networked, we don't want to copy it over into the table. - if (isNetworkedProperty) - { - continue; - } - } - else - { - // Remove the value we just pushed onto the stack - lua_pop(lua, 1); - } - } - lua_pushlstring(lua, prop->m_name.c_str(), prop->m_name.length()); if (prop->Write(*m_context)) { @@ -1157,7 +978,7 @@ namespace AzFramework return true; }; - serializeContext->Class() + serializeContext->Class() ->Version(3, converter) ->Field("ContextID", &ScriptComponent::m_contextId) ->Field("Properties", &ScriptComponent::m_properties) @@ -1174,8 +995,6 @@ namespace AzFramework AZ::ScriptProperties::Reflect(reflection); } } - - ScriptNetBindingTable::Reflect(reflection); } //========================================================================= diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h index 4d15bc527d..8294f3849c 100644 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h +++ b/Code/Framework/AzFramework/AzFramework/Script/ScriptComponent.h @@ -20,8 +20,6 @@ #include #include -#include - namespace AZ { class ScriptProperty; @@ -37,8 +35,6 @@ namespace AzToolsFramework namespace AzFramework { - class ScriptNetBindingTable; - struct ScriptCompileRequest; using WriteFunction = AZStd::function< AZ::Outcome(const ScriptCompileRequest&, AZ::IO::GenericStream& in, AZ::IO::GenericStream& out) >; @@ -92,15 +88,13 @@ namespace AzFramework class ScriptComponent : public AZ::Component , private AZ::Data::AssetBus::Handler - , public AzFramework::NetBindable { friend class AzToolsFramework::Components::ScriptEditorComponent; public: - static const char* NetRPCFieldName; static const char* DefaultFieldName; - AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", NetBindable); + AZ_COMPONENT(AzFramework::ScriptComponent, "{8D1BC97E-C55D-4D34-A460-E63C57CD0D4B}", AZ::Component); /// \red ComponentDescriptor::Reflect static void Reflect(AZ::ReflectContext* reflection); @@ -116,7 +110,6 @@ namespace AzFramework // Methods used for unit tests AZ::ScriptProperty* GetScriptProperty(const char* propertyName); - const AZ::ScriptProperty* GetNetworkedScriptProperty(const char* propertyName) const; protected: ScriptComponent(const ScriptComponent&) = delete; @@ -133,13 +126,6 @@ namespace AzFramework void OnAssetReloaded(AZ::Data::Asset asset) override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // NetBindable - GridMate::ReplicaChunkPtr GetNetworkBinding() override; - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) override; - void UnbindFromNetwork() override; - ////////////////////////////////////////////////////////////////////////// - /// Load script (unless already by other instances) and creates the script instance into the VM void LoadScript(); /// Removes the script instance and unloads the script (unless needed by other instances) @@ -152,8 +138,6 @@ namespace AzFramework void CreateEntityTable(); void DestroyEntityTable(); - void CreateNetworkBindingTable(int baseStackIndex, int entityStackIndex); - void CreatePropertyGroup(const ScriptPropertyGroup& group, int propertyGroupTableIndex, int parentIndex, int metatableIndex, bool isRoot); AZ::ScriptContext* m_context; ///< Context in which the script will be running @@ -161,7 +145,6 @@ namespace AzFramework AZ::Data::Asset m_script; ///< Reference to the script asset used for this component. int m_table; ///< Cached table index ScriptPropertyGroup m_properties; ///< List with all properties that were tweaked in the editor and should override values in the m_sourceScriptName class inside m_script. - ScriptNetBindingTable* m_netBindingTable; ///< Table that will hold our networked script values, and manage callbacks }; } // namespace AZ diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp deleted file mode 100644 index f02e050e74..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.cpp +++ /dev/null @@ -1,573 +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 -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "AzFramework/Script/ScriptMarshal.h" - -namespace AzFramework -{ - //////////////////////////// - // ScriptPropertyMarshaler - //////////////////////////// - - template - bool UnmarshalGenericType(AZ::DynamicSerializableField& serializableField, GridMate::ReadBuffer& rb) - { - bool valueChanged = true; - - GridMate::Marshaler serializableFieldMarshaler; - - // Store the old value, to compare with the unmarshaled value, to signal - T oldValue = (*serializableField.Get()); - - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - if (serializableField.m_typeId == T::TYPEINFO_Uuid()) - { - valueChanged = !(oldValue == (*serializableField.Get())); - } - - return valueChanged; - } - - class ScriptPropertyTableMarshalerHelper - { - public: - template - static void MarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, GridMate::WriteBuffer& wb, const AZ::ScriptPropertyTable* scriptPropertyTable) - { - GridMate::Marshaler sizeMarshaler; - - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - // We will write out all of our keys. Since it is easier to write out nil values for the properties. - sizeMarshaler.Marshal(wb,static_cast(valueMap.size())); - - GridMate::Marshaler keyMarshaler; - - for (auto& mapPair : valueMap) - { - keyMarshaler.Marshal(wb,mapPair.first); - scriptPropertyMarshaler.Marshal(wb,mapPair.second.m_valueProperty); - } - } - else - { - sizeMarshaler.Marshal(wb,0); - } - } - - template - static bool UnmarshalScriptPropertyGenericMap(const ScriptPropertyMarshaler& scriptPropertyMarshaler, AZ::ScriptPropertyTable* scriptPropertyTable, GridMate::ReadBuffer& rb) - { - bool valueChanged = false; - - AZ::SerializeContext* useContext = nullptr; - EBUS_EVENT_RESULT(useContext, AZ::ComponentApplicationBus, GetSerializeContext); - - if (useContext) - { - const AZ::SerializeContext::ClassData* classData = useContext->FindClassData(T::TYPEINFO_Uuid()); - - if (classData && classData->m_factory) - { - auto mapIter = scriptPropertyTable->m_genericMapping.find(T::TYPEINFO_Uuid()); - - if (mapIter != scriptPropertyTable->m_genericMapping.end()) - { - // This whole thing is an in-place map update. - // to try to minimize the number of allocations. We try to re-use objects as much as possible. - // - // Two phase approach: Step one, update all of the existing properties, while keeping track of all of the used keys. - // Step two, go through and delete any unupdated keys from the mapping. - AZ::ScriptPropertyGenericClassMapImpl* genericClassKeyMap = static_cast*>(mapIter->second); - - AZStd::unordered_set newKeys; - - GridMate::Marshaler sizeMarshaler; - - AZ::u32 mapSize; - sizeMarshaler.Unmarshal(mapSize,rb); - - auto& valueMap = genericClassKeyMap->GetPairMapping(); - - GridMate::Marshaler keyMarshaler; - - for (unsigned int i=0; i < mapSize; ++i) - { - T propertyKey; - keyMarshaler.Unmarshal(propertyKey,rb); - - newKeys.insert(propertyKey); - - auto valueIter = valueMap.find(propertyKey); - - if (valueIter != valueMap.end()) - { - if (scriptPropertyMarshaler.UnmarshalToPointer(valueIter->second.m_valueProperty,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* newValueProperty = nullptr; - scriptPropertyMarshaler.UnmarshalToPointer(newValueProperty,rb); - - AZ::ScriptPropertyGenericClassMap::MapValuePair newPair; - - newPair.m_valueProperty = newValueProperty; - - T* serializableData = nullptr; - serializableData = static_cast(classData->m_factory->Create("ScriptProperty")); - (*serializableData) = propertyKey; - - AZ::ScriptPropertyGenericClass* genericPropertyClass = aznew AZ::ScriptPropertyGenericClass(); - - genericPropertyClass->Set(serializableData); - - newPair.m_keyProperty = genericPropertyClass; - - valueMap.emplace(propertyKey,newPair); - } - } - - // Delete all of the unused keyes from the map - auto valueIter = valueMap.begin(); - - while (valueIter != valueMap.end()) - { - if (newKeys.find(valueIter->first) == newKeys.end()) - { - valueChanged = true; - valueIter->second.Destroy(); - valueIter = valueMap.erase(valueIter); - } - else - { - ++valueIter; - } - } - } - } - } - - return valueChanged; - } - }; - - - - void ScriptPropertyMarshaler::Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& property) const - { - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - if (property == nullptr) - { - // Write out a nil property if we have a nullptr property - nameMarshaler.Marshal(wb,""); - idMarshaler.Marshal(wb,0); - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - return; - } - - // Common points: - // Always going to marshal the uuid of the type(or something similar) - // so we know what type we have on the other side. - // - // Next need to pass along the name field. - const AZ::Uuid& typeId = azrtti_typeid(property); - - nameMarshaler.Marshal(wb,property->m_name); - idMarshaler.Marshal(wb,property->m_id); - - // Method 1: - // - Allow each ScriptProperty to marshal itself. - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate. - // cont.Marshal(wb); - - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler doubleMarshaler; - doubleMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Marshal(wb,static_cast(property)->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - const AZ::DynamicSerializableField& serializableField = static_cast(property)->GetSerializableField(); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Marshal(wb,serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::TYPEINFO_Uuid()) - { - const AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(property); - - typeMarshaler.Marshal(wb,typeId); - - GridMate::Marshaler mapSizeMarshaler; - mapSizeMarshaler.Marshal(wb,static_cast(scriptPropertyTable->m_indexMapping.size())); - - GridMate::Marshaler indexMarshaler; - - // Currently only support integers as keys inside of the table. - for (auto& mapPair : scriptPropertyTable->m_indexMapping) - { - indexMarshaler.Marshal(wb,mapPair.first); - this->Marshal(wb,mapPair.second); - } - - mapSizeMarshaler.Marshal(wb, static_cast(scriptPropertyTable->m_keyMapping.size())); - - GridMate::Marshaler hashMarshaler; - - for (auto& mapPair : scriptPropertyTable->m_keyMapping) - { - // For hashed values. The name of the script property is the same as the hash it should be using. - // We still synchronize the Crc so we can unmarshal in place on the other side. - hashMarshaler.Marshal(wb,mapPair.first); - Marshal(wb,mapPair.second); - } - - // EntityId's - ScriptPropertyTableMarshalerHelper::MarshalScriptPropertyGenericMap((*this), wb, scriptPropertyTable); - } - else - { - typeMarshaler.Marshal(wb,AZ::ScriptPropertyNil::RTTI_Type()); - } - } - - bool ScriptPropertyMarshaler::UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const - { - bool typeChanged = false; - AZ::Uuid typeId; - AZ::u64 id; - AZStd::string name; - - GridMate::Marshaler typeMarshaler; - GridMate::Marshaler idMarshaler; - GridMate::Marshaler nameMarshaler; - - nameMarshaler.Unmarshal(name,rb); - idMarshaler.Unmarshal(id,rb); - typeMarshaler.Unmarshal(typeId,rb); - - if (target == nullptr || typeId != azrtti_typeid(target)) - { - typeChanged = true; - - AZ::ScriptProperty* actualScriptProperty = nullptr; - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyBoolean(); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyNumber(); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyString(); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyGenericClass(); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - actualScriptProperty = aznew AZ::ScriptPropertyTable(); - } - else - { - actualScriptProperty = aznew AZ::ScriptPropertyNil(); - } - - actualScriptProperty->m_name = name; - delete target; - - target = actualScriptProperty; - } - - // Update our ID - target->m_id = id; - - // Method 1: - // - Allow each ScriptProperty to unmarshal itself - // - Currently unavailable since the ScriptProperties live in AZCore - // and the WriteBuffer is in GridMate - // actualScriptProperty->Unmarshal(rb); - // - // Method 2: - // - Process all of our known marshallable types and use the appropriate marshaler - - bool valueChanged = false; - - if (typeId == AZ::ScriptPropertyBoolean::RTTI_Type()) - { - AZ::ScriptPropertyBoolean* booleanProperty = static_cast(target); - bool oldValue = booleanProperty->m_value; - - GridMate::Marshaler boolMarshaler; - boolMarshaler.Unmarshal(booleanProperty->m_value,rb); - - valueChanged = !(oldValue == booleanProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyString::RTTI_Type()) - { - AZ::ScriptPropertyString* stringProperty = static_cast(target); - AZStd::string oldValue = stringProperty->m_value; - - GridMate::Marshaler stringMarshaler; - stringMarshaler.Unmarshal(stringProperty->m_value,rb); - - valueChanged = !(oldValue == stringProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyNumber::RTTI_Type()) - { - AZ::ScriptPropertyNumber* numberProperty = static_cast(target); - double oldValue = numberProperty->m_value; - - GridMate::Marshaler numberMarshaler; - numberMarshaler.Unmarshal(numberProperty->m_value,rb); - - valueChanged = !(oldValue == numberProperty->m_value); - } - else if (typeId == AZ::ScriptPropertyGenericClass::RTTI_Type()) - { - AZ::ScriptPropertyGenericClass* genericProperty = static_cast(target); - - AZ::DynamicSerializableField& serializableField = genericProperty->m_value; - - AZ::DynamicSerializableField oldField; - - oldField.CopyDataFrom(serializableField); - - GridMate::Marshaler serializableFieldMarshaler; - serializableFieldMarshaler.Unmarshal(serializableField,rb); - - // If our type hasn't changed, compare the values. - valueChanged = !oldField.IsEqualTo(serializableField); - } - else if (typeId == AZ::ScriptPropertyTable::RTTI_Type()) - { - AZ::ScriptPropertyTable* scriptPropertyTable = static_cast(target); - GridMate::Marshaler mapSizeMarshaler; - - // Unmarshal all of the indexes properties - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newIndexes; - GridMate::Marshaler indexMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - int index = 0; - indexMarshaler.Unmarshal(index,rb); - - auto mapIter = scriptPropertyTable->m_indexMapping.find(index); - - if (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto insertResult = scriptPropertyTable->m_indexMapping.emplace(index,scriptProperty); - mapIter = insertResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - newIndexes.insert(index); - } - } - - auto mapIter = scriptPropertyTable->m_indexMapping.begin(); - - while (mapIter != scriptPropertyTable->m_indexMapping.end()) - { - if (newIndexes.find(mapIter->first) == newIndexes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_indexMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the hashed values - { - AZ::u32 mapSize = 0; - mapSizeMarshaler.Unmarshal(mapSize, rb); - - AZStd::unordered_set newHashes; - GridMate::Marshaler hashMarshaler; - - for (AZ::u32 i=0; i < mapSize; ++i) - { - AZ::u32 newHash; - hashMarshaler.Unmarshal(newHash, rb); - - auto mapIter = scriptPropertyTable->m_keyMapping.find(newHash); - - if (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (UnmarshalToPointer(mapIter->second,rb)) - { - valueChanged = true; - } - } - else - { - valueChanged = true; - - AZ::ScriptProperty* scriptProperty = nullptr; - UnmarshalToPointer(scriptProperty,rb); - auto emplaceResult = scriptPropertyTable->m_keyMapping.emplace(newHash,scriptProperty); - mapIter = emplaceResult.first; - } - - if (mapIter->second == nullptr || azrtti_istypeof(mapIter->second)) - { - valueChanged = true; - - delete mapIter->second; - scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - newHashes.insert(newHash); - } - } - - auto mapIter = scriptPropertyTable->m_keyMapping.begin(); - - while (mapIter != scriptPropertyTable->m_keyMapping.end()) - { - if (newHashes.find(mapIter->first) == newHashes.end()) - { - valueChanged = true; - - delete mapIter->second; - mapIter = scriptPropertyTable->m_keyMapping.erase(mapIter); - } - else - { - ++mapIter; - } - } - } - - // Unmarshal all of the generic properties - - // EntityId's - if (ScriptPropertyTableMarshalerHelper::UnmarshalScriptPropertyGenericMap((*this), scriptPropertyTable, rb)) - { - valueChanged = true; - } - } - - return typeChanged || valueChanged; - } - - //////////////////////////// - // ScriptPropertyThrottler - //////////////////////////// - - ScriptPropertyThrottler::ScriptPropertyThrottler() - : m_isDirty(true) - { - - } - - void ScriptPropertyThrottler::SignalDirty() - { - m_isDirty = true; - } - - bool ScriptPropertyThrottler::WithinThreshold(AZ::ScriptProperty* newValue) const - { - return newValue == nullptr || !m_isDirty; - } - - void ScriptPropertyThrottler::UpdateBaseline(AZ::ScriptProperty* baseline) - { - (void)baseline; - - m_isDirty = false; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h deleted file mode 100644 index c13749d46b..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptMarshal.h +++ /dev/null @@ -1,94 +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. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H -#define AZFRAMEWORK_SCRIPT_SCRIPTMARSHAL_H - -#include - -#include - -namespace AZ -{ - class ScriptProperty; -} - -namespace AzFramework -{ - /** - * Specalized helper marshaler for ScriptProperty class - */ - class ScriptPropertyMarshaler - { - public: - void Marshal(GridMate::WriteBuffer& wb, AZ::ScriptProperty*const& cont) const; - bool UnmarshalToPointer(AZ::ScriptProperty*& target, GridMate::ReadBuffer& rb) const; - }; - - class ScriptPropertyThrottler - { - public: - ScriptPropertyThrottler(); - - void SignalDirty(); - bool WithinThreshold(AZ::ScriptProperty* newValue) const; - void UpdateBaseline(AZ::ScriptProperty* baseline); - - private: - bool m_isDirty; - }; - - /** - * Specialized helper marshaler to help with the vector creation/destruction - */ - class ScriptRPCMarshaler - { - public: - - typedef AZStd::vector< AZ::ScriptProperty* > Container; - - ScriptRPCMarshaler() - { - } - - AZ_FORCE_INLINE void Marshal(GridMate::WriteBuffer& wb, const Container& container) const - { - AZ_Assert(container.size() < USHRT_MAX, "Container has too many elements for marshaling!"); - AZ::u16 size = static_cast(container.size()); - wb.Write(size); - for (const auto& i : container) - { - m_marshaler.Marshal(wb, i); - } - } - - AZ_FORCE_INLINE void Unmarshal(Container& container, GridMate::ReadBuffer& rb) const - { - container.clear(); - - AZ::u16 size; - rb.Read(size); - container.reserve(size); - - for (AZ::u16 i = 0; i < size; ++i) - { - AZ::ScriptProperty* readProperty = nullptr; - m_marshaler.UnmarshalToPointer(readProperty, rb); - container.insert(container.end(), readProperty); - } - } - - protected: - ScriptPropertyMarshaler m_marshaler; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp deleted file mode 100644 index 45690eac01..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.cpp +++ /dev/null @@ -1,1427 +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 - -#include -#include - -#include - -extern "C" { -# include -# include -} - -namespace AzFramework -{ - namespace Internal - { - static int NetBinding__IsAuthoritative(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - //AZ_Assert(netBindingTable != nullptr && netBindingTable->GetScriptContext(),"Missing or misconfigured ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - lua_pushboolean(lua,netBindingTable->IsMaster()); - } - else - { - // If we don't have a net binding table, or a a script context, return true - // since we likely are the master. - lua_pushboolean(lua,true); - } - - return 1; - } - - static int NetBinding__IsMaster(lua_State* lua) - { - AZ_Warning("ScriptNetBindings", false, "IsMaster deprecated for the more lexical consistent IsAuthoritative"); - return NetBinding__IsAuthoritative(lua); - } - - static int NetBinding__CallRPC(lua_State* lua) - { - ScriptNetBindingTable* netBindingTable = reinterpret_cast(lua_touserdata(lua,lua_upvalueindex(1))); - - AZ_Error("ScriptComponent", netBindingTable != nullptr,"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - AZ_Error("ScriptComponent", netBindingTable == nullptr || netBindingTable->GetScriptContext(),"Missing ScriptNetBindingTable as upvalue in lua_cclosure"); - if (netBindingTable && netBindingTable->GetScriptContext()) - { - AZ::ScriptContext* context = netBindingTable->GetScriptContext(); - - AZ::ScriptDataContext stackContext; - bool validIndex = context->ReadStack(stackContext); - - if (validIndex) - { - netBindingTable->InvokeRPC(stackContext); - } - } - - return 0; - } - } - - ////////////////////////// - // ScriptPropertyDataSet - ////////////////////////// - - // Necessary since the field doesn't make a copy, but keeps the actual literal. - // But overall :( - - const char* ScriptPropertyDataSet::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++]; - } - - ScriptPropertyDataSet::ScriptPropertyDataSet() - : ScriptPropertyDataSetType(GetDataSetName()) - , m_reserver(nullptr) - { - } - - ScriptPropertyDataSet::~ScriptPropertyDataSet() - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->DisableInPlaceControls(); - functionalScriptProperty->RemoveWatcher(this); - } - } - - void ScriptPropertyDataSet::Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || reserver == m_reserver, "Trying to reserve the same DataSet for two NetworkedTableVaules."); - - if (m_reserver == nullptr) - { - m_reserver = reserver; - AZ::ScriptPropertyWatcherBus::Handler::BusConnect(this); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(Get()); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - } - - void ScriptPropertyDataSet::Release(ScriptNetBindingTable::NetworkedTableValue* reserver) - { - AZ_Error("ScriptComponent",m_reserver == nullptr || m_reserver == reserver, "Incorrect NetworkedTableValue trying to release a reserver DataSet."); - if (m_reserver == reserver) - { - m_reserver = nullptr; - AZ::ScriptPropertyWatcherBus::Handler::BusDisconnect(this); - } - } - - bool ScriptPropertyDataSet::IsReserved() const - { - return m_reserver != nullptr; - } - - bool ScriptPropertyDataSet::UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool wroteValue = false; - - Modify([&](AZ::ScriptProperty*& scriptProperty) - { - wroteValue = true; - if (scriptProperty == nullptr || !scriptProperty->TryRead(scriptDataContext,-1)) - { - AZ::ScriptProperty* newPropertyType = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - delete scriptProperty; - - if (newPropertyType == nullptr) - { - scriptProperty = aznew AZ::ScriptPropertyNil(); - } - else - { - scriptProperty = newPropertyType; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(newPropertyType); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - } - - m_throttler.SignalDirty(); - - return wroteValue; - }); - - return wroteValue; - } - - void ScriptPropertyDataSet::SetScriptProperty(AZ::ScriptProperty* scriptProperty) - { - Modify([&](AZ::ScriptProperty*& dataSetProperty) - { - AZ::ScriptProperty* tempProperty = dataSetProperty; - - if (scriptProperty == nullptr) - { - if (tempProperty) - { - dataSetProperty = aznew AZ::ScriptPropertyNil(tempProperty->m_name.c_str()); - } - else - { - dataSetProperty = aznew AZ::ScriptPropertyNil(); - } - } - else - { - dataSetProperty = scriptProperty; - } - - if (tempProperty) - { - delete tempProperty; - } - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(dataSetProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - functionalScriptProperty->AddWatcher(this); - } - - m_throttler.SignalDirty(); - - return true; - }); - } - - void ScriptPropertyDataSet::OnObjectModified() - { - m_throttler.SignalDirty(); - SetDirty(); - } - - //////////////////////// - // EntityScriptContext - //////////////////////// - - ScriptNetBindingTable::EntityScriptContext::EntityScriptContext() - : m_scriptContext(nullptr) - , m_entityTableRegistryIndex(LUA_REFNIL) - { - } - - void ScriptNetBindingTable::EntityScriptContext::Unload() - { - m_scriptContext = nullptr; - m_entityTableRegistryIndex = LUA_REFNIL; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex != LUA_REFNIL; - } - - int ScriptNetBindingTable::EntityScriptContext::GetEntityTableRegistryIndex() const - { - return m_entityTableRegistryIndex; - } - - bool ScriptNetBindingTable::EntityScriptContext::HasScriptContext() const - { - return m_scriptContext != nullptr; - } - - AZ::ScriptContext* ScriptNetBindingTable::EntityScriptContext::GetScriptContext() const - { - return m_scriptContext; - } - - void ScriptNetBindingTable::EntityScriptContext::ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_scriptContext = scriptContext; - m_entityTableRegistryIndex = entityTableRegistryIndex; - - AZ_Error("ScriptComponent",SanityCheckContext(),"Invalid configuration given to ScriptNetBindingTable"); - } - - bool ScriptNetBindingTable::EntityScriptContext::SanityCheckContext() const - { - bool isSane = HasScriptContext(); - - if (isSane) - { - // We want to check if our reference is actually pointing to a table - // which we will assume is our entity table - lua_State* nativeContext = m_scriptContext->NativeContext(); - - lua_rawgeti(nativeContext,LUA_REGISTRYINDEX,m_entityTableRegistryIndex); - isSane = lua_istable(nativeContext,-1); - lua_pop(nativeContext,1); - } - - return isSane; - } - - //////////////////////// - // NetworkedTableValue - //////////////////////// - - ScriptNetBindingTable::NetworkedTableValue::NetworkedTableValue(AZ::ScriptProperty* initialValue) - : m_shimmedScriptProperty(initialValue) - , m_dataSet(nullptr) - , m_forcedDataSetIndex(-1) - , m_functionReference(LUA_REFNIL) - { - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(initialValue); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - ScriptNetBindingTable::NetworkedTableValue::~NetworkedTableValue() - { - // Always want to release our dataset if we have one when we are destroyed. - // - // We do not want to delete our proeprty thought, since we might have been copied over. - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::Destroy() - { - if (m_shimmedScriptProperty) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - } - - if (m_dataSet) - { - m_dataSet->Release(this); - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasDataSet() const - { - return m_dataSet != nullptr; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterDataSet(ScriptPropertyDataSet* dataSet) - { - m_dataSet = dataSet; - - if (m_dataSet) - { - if (m_shimmedScriptProperty) - { - m_dataSet->SetScriptProperty(m_shimmedScriptProperty); - m_shimmedScriptProperty = nullptr; - } - - m_dataSet->Reserve(this); - } - } - - void ScriptNetBindingTable::NetworkedTableValue::UnbindFromDataSet() - { - if (m_dataSet) - { - // Take ownership of the DataSet script property into our shimmed value - // - // If we are the master, we can take ownership and set the data set value to null - if (m_dataSet->CanSet()) - { - m_shimmedScriptProperty = m_dataSet->Get(); - m_dataSet->Set(nullptr); - } - // Otherwise, we need to clone the data in the data set since we can't modify it and we need to avoid a double deletion. - else - { - AZ::ScriptProperty* scriptProperty = m_dataSet->Get(); - m_shimmedScriptProperty = scriptProperty->Clone(); - } - - m_dataSet->Release(this); - m_dataSet = nullptr; - } - } - - ScriptPropertyDataSet* ScriptNetBindingTable::NetworkedTableValue::GetDataSet() const - { - return m_dataSet; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasForcedDataSetIndex() const - { - return m_forcedDataSetIndex >= 1; - } - - void ScriptNetBindingTable::NetworkedTableValue::SetForcedDataSetIndex(int index) - { - m_forcedDataSetIndex = index; - } - - int ScriptNetBindingTable::NetworkedTableValue::GetForcedDataSetIndex() const - { - return m_forcedDataSetIndex; - } - - bool ScriptNetBindingTable::NetworkedTableValue::HasCallback() const - { - return m_functionReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::NetworkedTableValue::RegisterCallback(int functionReference) - { - AZ_Warning("ScriptComponent",!HasCallback() || functionReference == LUA_REFNIL,"Overriding an already registered callback for a DataSet."); - - m_functionReference = functionReference; - } - - void ScriptNetBindingTable::NetworkedTableValue::ReleaseCallback(AZ::ScriptContext& scriptContext) - { - if (HasCallback()) - { - scriptContext.ReleaseCached(m_functionReference); - m_functionReference = LUA_REFNIL; - } - } - - void ScriptNetBindingTable::NetworkedTableValue::InvokeCallback(EntityScriptContext& entityContext, const GridMate::TimeContext& timeContext) - { - (void)timeContext; - - AZ::ScriptContext* scriptContext = entityContext.GetScriptContext(); - - AZ_Warning("ScriptComponent",scriptContext,"DataSetCallback given null ScriptContext."); - AZ_Warning("ScriptComponent",entityContext.HasEntityTableRegistryIndex(),"DataSetCallback given invalid entity table reference"); - if (scriptContext && entityContext.HasEntityTableRegistryIndex()) - { - AZ::ScriptDataContext callContext; - - if (scriptContext->CallCached(m_functionReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityContext.GetEntityTableRegistryIndex()); - callContext.CallExecute(); - } - } - } - - bool ScriptNetBindingTable::NetworkedTableValue::AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName) - { - bool assignedValue = false; - if (HasDataSet()) - { - assignedValue = GetDataSet()->UpdateScriptProperty(scriptDataContext, propertyName); - } - else - { - if (m_shimmedScriptProperty == nullptr || !m_shimmedScriptProperty->TryRead(scriptDataContext,-1)) - { - delete m_shimmedScriptProperty; - m_shimmedScriptProperty = nullptr; - m_shimmedScriptProperty = scriptDataContext.ConstructScriptProperty(-1,propertyName.c_str()); - - AZ::FunctionalScriptProperty* functionalScriptProperty = azrtti_cast(m_shimmedScriptProperty); - - if (functionalScriptProperty) - { - functionalScriptProperty->EnableInPlaceControls(); - } - } - - assignedValue = (m_shimmedScriptProperty != nullptr); - } - - return assignedValue; - } - - bool ScriptNetBindingTable::NetworkedTableValue::InspectValue(AZ::ScriptContext* scriptContext) const - { - AZ::ScriptProperty* inspectedProperty = m_shimmedScriptProperty; - - if (HasDataSet()) - { - inspectedProperty = GetDataSet()->Get(); - } - - bool inspectedValue = false; - - if (inspectedProperty) - { - inspectedValue = inspectedProperty->Write((*scriptContext)); - } - - if (!inspectedValue) - { - inspectedValue = true; - - AZ::ScriptPropertyNil nilProperty; - nilProperty.Write((*scriptContext)); - } - - return inspectedValue; - } - - ////////////// - // RPCHelper - ////////////// - - // Maybe make this guy create the table himself? - // Encapsulate the whole binding process in here. - ScriptNetBindingTable::RPCBindingHelper::RPCBindingHelper() - : m_masterReference(LUA_REFNIL) - , m_proxyReference(LUA_REFNIL) - { - } - - ScriptNetBindingTable::RPCBindingHelper::~RPCBindingHelper() - { - } - - void ScriptNetBindingTable::RPCBindingHelper::ReleaseTableIndex(AZ::ScriptContext& scriptContext) - { - if (m_masterReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_masterReference); - m_masterReference = LUA_REFNIL; - } - - if (m_proxyReference != LUA_REFNIL) - { - scriptContext.ReleaseCached(m_proxyReference); - m_proxyReference = LUA_REFNIL; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::IsValid() const - { - // Proxy is optional, so we only care about having the master index. - return m_masterReference != LUA_REFNIL; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetMasterFunction(int masterReference) - { - AZ_Error("ScriptComponent",m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL, "Trying to rebind RPC master callback"); - - if (m_masterReference == LUA_REFNIL || masterReference == LUA_REFNIL) - { - m_masterReference = masterReference; - } - } - - bool ScriptNetBindingTable::RPCBindingHelper::InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Invoking RPC with invalid ScriptContext"); - return false; - } - - bool allowRPC = false; - - if (m_masterReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_masterReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - if (callContext.CallExecute()) - { - bool hasResult = false; - if (callContext.GetNumResults() == 1) - { - hasResult = callContext.ReadResult(0,allowRPC); - } - - AZ_Assert(hasResult,"Master RPC function needs to return a boolean value"); - (void)hasResult; - } - } - - } - - return allowRPC; - } - - void ScriptNetBindingTable::RPCBindingHelper::SetProxyFunction(int proxyReference) - { - AZ_Error("ScriptComponent",m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL,"Trying to rebind an RPC Proxy call."); - - if (m_proxyReference == LUA_REFNIL || proxyReference == LUA_REFNIL) - { - m_proxyReference = proxyReference; - } - } - - void ScriptNetBindingTable::RPCBindingHelper::InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params) - { - if (!entityScriptContext.HasScriptContext()) - { - AZ_Error("ScriptComponent",false,"Trying to call a callback without a script context."); - return; - } - - AZ_Warning("ScriptComponent",m_proxyReference != LUA_REFNIL,"Trying to invoke an RPC on the proxy without a callback being set."); - if (m_proxyReference != LUA_REFNIL) - { - AZ::ScriptDataContext callContext; - AZ::ScriptContext* scriptContext = entityScriptContext.GetScriptContext(); - - if (scriptContext->CallCached(m_proxyReference,callContext)) - { - callContext.PushArgFromRegistryIndex(entityScriptContext.GetEntityTableRegistryIndex()); - - for (AZ::ScriptProperty* property : params) - { - callContext.PushArgScriptProperty(property); - } - - callContext.CallExecute(); - } - } - } - - ////////////////////////// - // ScriptNetBindingTable - ////////////////////////// - void ScriptNetBindingTable::Reflect(AZ::ReflectContext* reflection) - { - NetworkContext* netContext = azrtti_cast(reflection); - - if (netContext) - { - // Using old method until we update the network context to allow for array offests. - // Or find a better way to handle the script replica chunk - if (!GridMate::ReplicaChunkDescriptorTable::Get().FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(ScriptComponentReplicaChunk::GetChunkName()))) - { - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - } - } - - // Template specialization for the ConvertPropertyArrayToTable GenericClass support to deal with extra memory copies. - template<> - AZ::ScriptPropertyTable* ScriptNetBindingTable::ConvertPropertyArrayToTable(AZ::ScriptPropertyGenericClassArray* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - AZ::ScriptPropertyGenericClass emptyGenericClass; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - // - // To avoid pointlessly double copying the data. Insert the empty class. - scriptPropertyTable->SetTableValue(i+1, &emptyGenericClass); - - // Then do a find for the class back, to load up the data into the final object directly. - AZ::ScriptPropertyGenericClass* ownedClass = static_cast(scriptPropertyTable->FindTableValue(i+1)); - - const AZ::DynamicSerializableField& serializableField = arrayProperty->m_values[i]; - - ownedClass->Set(serializableField); - } - - return scriptPropertyTable; - } - - ScriptNetBindingTable::ScriptNetBindingTable() - { - } - - ScriptNetBindingTable::~ScriptNetBindingTable() - { - - } - - void ScriptNetBindingTable::Unload() - { - // Unbind our elements from our script context. - if (m_entityScriptContext.HasScriptContext()) - { - AZ::ScriptContext& scriptContext = (*m_entityScriptContext.GetScriptContext()); - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - NetworkedTableValue& tableValue = tablePair.second; - tableValue.ReleaseCallback(scriptContext); - } - - for (RPCHelperMap::value_type& rpcPair : m_rpcHelperMap) - { - RPCBindingHelper& bindingHelper = rpcPair.second; - bindingHelper.ReleaseTableIndex(scriptContext); - } - } - - // Destroy the table values, since they might contain some memory - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.Destroy(); - } - - m_networkedTable.clear(); - m_rpcHelperMap.clear(); - - m_entityScriptContext.Unload(); - } - - void ScriptNetBindingTable::CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex) - { - (void)baseTableIndex; - - lua_State* nativeContext = scriptContext->NativeContext(); - - lua_pushliteral(nativeContext,"IsMaster"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsMaster,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushliteral(nativeContext,"IsAuthoritative"); - lua_pushlightuserdata(nativeContext,this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__IsAuthoritative,1); - lua_rawset(nativeContext,entityTableIndex); - - lua_pushstring(nativeContext,ScriptComponent::NetRPCFieldName); - lua_createtable(nativeContext,0,0); - - int rpcTableIndex = lua_gettop(nativeContext); - - // Read the stack - AZ::ScriptDataContext stackContext; - if (scriptContext->ReadStack(stackContext)) - { - // Inspect the element we know to be our table context - AZ::ScriptDataContext entityDataContext; - if (stackContext.IsTable(baseTableIndex) && stackContext.InspectTable(baseTableIndex,entityDataContext)) - { - // Find our RPC table inside of baseTableIndex - int tableIndex = 0; - if (entityDataContext.PushTableElement(ScriptComponent::NetRPCFieldName,&tableIndex)) - { - // If it's a table, we want to inspect it. - AZ::ScriptDataContext rpcTable; - if (entityDataContext.IsTable(tableIndex) && entityDataContext.InspectTable(tableIndex,rpcTable)) - { - // Iterate over the fields here, and register and RPC for each element inside of that table. - int fieldIndex; - int elementIndex; - const char* fieldName; - - while (rpcTable.InspectNextElement(elementIndex, fieldName, fieldIndex)) - { - if (fieldName != nullptr) - { - RegisterRPC(rpcTable,fieldName,elementIndex,rpcTableIndex); - } - } - } - } - } - } - - lua_rawset(nativeContext,entityTableIndex); - } - - void ScriptNetBindingTable::FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex) - { - m_entityScriptContext.ConfigureContext(scriptContext, entityTableRegistryIndex); - - if (m_replicaChunk) - { - AssignDataSets(); - } - } - - AZ::ScriptContext* ScriptNetBindingTable::GetScriptContext() const - { - return m_entityScriptContext.GetScriptContext(); - } - - bool ScriptNetBindingTable::IsMaster() const - { - return (m_replicaChunk != nullptr) ? m_replicaChunk->IsMaster() : true; - } - - bool ScriptNetBindingTable::AssignTableValue(AZ::ScriptDataContext& stackDataContext) - { - bool wroteValue = false; - AZ_Error("ScriptComponent",stackDataContext.GetScriptContext() == m_entityScriptContext.GetScriptContext(),"Trying to use a ScriptNetBindings in the wrong context."); - - // We do not want to allow assignments on proxy replicas - // since that information will be discarded anyway. - if ((m_replicaChunk && !m_replicaChunk->IsMaster()) || (stackDataContext.GetScriptContext() != m_entityScriptContext.GetScriptContext())) - { - return false; - } - - AZStd::string key; - - if (stackDataContext.ReadValue(-2,key)) - { - NetworkedTableValue* networkedTableValue = FindTableValue(key); - - // If we don't have the value, it means we aren't trying to network it. - if (networkedTableValue) - { - if (m_replicaChunk && !networkedTableValue->HasDataSet()) - { - ScriptComponentReplicaChunk* scriptChunk = static_cast(m_replicaChunk.get()); - - scriptChunk->AssignDataSet((*networkedTableValue)); - } - - wroteValue = networkedTableValue->AssignValue(stackDataContext,key); - } - } - - return wroteValue; - } - - bool ScriptNetBindingTable::InspectTableValue(AZ::ScriptDataContext& stackContext) const - { - bool readValue = false; - AZStd::string key; - - if (stackContext.ReadValue(-1,key)) - { - AZ::ScriptContext* scriptContext = stackContext.GetScriptContext(); - - if (scriptContext) - { - const NetworkedTableValue* networkTableValue = FindTableValue(key); - - if (networkTableValue) - { - readValue = networkTableValue->InspectValue((stackContext.GetScriptContext())); - - // Default to nil if we have a network table value registered, but couldn't - // inspect it for some reason. - if (!readValue) - { - readValue = true; - static AZ::ScriptPropertyNil s_nilValue; - s_nilValue.Write((*scriptContext)); - } - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to read value into invalid ScriptContext"); - } - } - - return readValue; - } - - bool ScriptNetBindingTable::RegisterDataSet(AZ::ScriptDataContext& networkTableContext, AZ::ScriptProperty* scriptProperty) - { - if (scriptProperty == nullptr) - { - AZ_Error("ScriptComponent",false,"Trying to Create a dataset for a null script property."); - return false; - } - - AZ::Uuid typeId = azrtti_typeid(scriptProperty); - - if ( typeId == azrtti_typeid() - || typeId == azrtti_typeid()) - { - AZ_Error("ScriptComponent",false,"Using unsupported type for ScriptProperty(%s) net binding. Value will not be networked.", scriptProperty->m_name.c_str()); - return false; - } - - // If we've already got an item inside of our network table. - // We need to surpress that problem, since it may happen when we reload the script - if (m_networkedTable.find(scriptProperty->m_name) != m_networkedTable.end()) - { - return true; - } - - int elementIndex; - bool enabled = false; - bool handledProperty = false; - - if (networkTableContext.PushTableElement("Enabled",&elementIndex)) - { - // If we have the enabled field and it's not a boolean. - // Assume false. - if (networkTableContext.IsBoolean(elementIndex)) - { - // If we didn't read in the enabled value, assume it's false. - if (!networkTableContext.ReadValue(elementIndex,enabled)) - { - enabled = false; - } - } - } - else - { - // If we don't have an enabled field, assume that we want to be bound. - enabled = true; - } - - if (enabled) - { - NetworkedTableValue networkedTableValue; - - // Convert the property arrays over to a table to simplify the logic flow of detecting - // the various changes, and to more readily support what the general LUA syntax. - if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyBooleanArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyNumberArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyStringArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else if (typeId == azrtti_typeid()) - { - AZ::ScriptPropertyGenericClassArray* sourceArray = static_cast(scriptProperty); - - networkedTableValue = NetworkedTableValue(ConvertPropertyArrayToTable(sourceArray)); - } - else - { - networkedTableValue = NetworkedTableValue(scriptProperty->Clone()); - } - - if (networkTableContext.PushTableElement("OnNewValue", &elementIndex)) - { - if (networkTableContext.IsFunction(elementIndex)) - { - networkedTableValue.RegisterCallback( networkTableContext.CacheValue(elementIndex) ); - } - } - - if (networkTableContext.PushTableElement("ForceIndex",&elementIndex)) - { - if (networkTableContext.IsNumber(elementIndex)) - { - int forcedDataSetIndex = 0; - if (networkTableContext.ReadValue(elementIndex,forcedDataSetIndex)) - { - AZ_Error("ScriptComponent",forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets,"Trying to force Property (%s) to an invalid DataSetIndex(%i).",scriptProperty->m_name.c_str(),forcedDataSetIndex); - if(forcedDataSetIndex >= 1 && forcedDataSetIndex <= ScriptComponentReplicaChunk::k_maxScriptableDataSets) - { - networkedTableValue.SetForcedDataSetIndex(forcedDataSetIndex); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to force Property (%s) to unknown DataSetIndex. Ignoring field.", scriptProperty->m_name.c_str()); - } - } - } - - AZStd::pair insertResult = m_networkedTable.insert(NetworkedTableMap::value_type(scriptProperty->m_name,networkedTableValue)); - - // If we failed to insert the object, we need to destroy the networked table value. - // To avoid leaking memory - if (!insertResult.second) - { - networkedTableValue.Destroy(); - } - - handledProperty = true; - } - - return handledProperty; - } - - bool ScriptNetBindingTable::InvokeRPC(AZ::ScriptDataContext& stackContext) - { - lua_State* nativeContext = stackContext.GetScriptContext()->NativeContext(); - - bool invokedRPC = false; - AZStd::string rpcName; - - // Assuming this is coming from an __call metamethod - // the lua stack will look as follows - // 1 - Table - // n - Params - if (stackContext.IsTable(1)) - { - // Get the RPC name - lua_pushliteral(nativeContext,"_rpcName"); - lua_gettable(nativeContext,1); - - if (stackContext.IsString(-1)) - { - if (stackContext.ReadValue(-1,rpcName)) - { - // Pop off the key value we just read in; It's no longer necessary - lua_pop(nativeContext,1); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(rpcName); - - if (rpcIter != m_rpcHelperMap.end()) - { - bool foundParams = true; - - ScriptRPCMarshaler::Container paramContainer; - - // Need to start at 2, since 1 is our table. - for (int i=2; i <= lua_gettop(nativeContext); ++i) - { - AZ::ScriptProperty* property = stackContext.ConstructScriptProperty(i,"param"); - - if (property) - { - paramContainer.push_back(property); - } - else - { - foundParams = false; - break; - } - } - - // The script marshaler will clean up the keys after it has marshalled them out. - if (foundParams) - { - invokedRPC = true; - - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - scriptReplicaChunk->m_scriptRPC(rpcName,paramContainer); - } - else - { - rpcIter->second.InvokeMaster(m_entityScriptContext,paramContainer); - } - } - else - { - for (AZ::ScriptProperty* property : paramContainer) - { - delete property; - } - - paramContainer.clear(); - } - } - } - else - { - // We failed to read, so we need to pop the value we pushed off the stack. - lua_pop(nativeContext,1); - } - } - else - { - // Pop off the value we added to the top of the stack - lua_pop(nativeContext,1); - } - } - - return invokedRPC; - } - - void ScriptNetBindingTable::RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpc, int elementIndex, int tableStackIndex) - { - if (rpcTableContext.IsTable(elementIndex)) - { - RPCBindingHelper helper; - - AZ::ScriptDataContext rpcContext; - if (rpcTableContext.InspectTable(elementIndex,rpcContext)) - { - int functionIndex = 0; - if (rpcContext.PushTableElement("OnMaster",&functionIndex)) - { - helper.SetMasterFunction(rpcContext.CacheValue(functionIndex)); - } - else - { - AZ_Error("ScriptNetBinding", false, "Could not find OnMaster function for RPC (%s).", rpc.c_str()); - } - - if (rpcContext.PushTableElement("OnProxy",&functionIndex)) - { - helper.SetProxyFunction(rpcContext.CacheValue(functionIndex)); - } - } - else - { - AZ_Error("ScriptNetBinding", false, "Could inspect table for RPC (%s).", rpc.c_str()); - } - - if (helper.IsValid()) - { - lua_State* nativeContext = rpcTableContext.GetScriptContext()->NativeContext(); - - // Create the RPC Table inside of our entity table to allow for functions to be called on it. - // - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_createtable(nativeContext,0,1); - - // Set up a name field inside of the table - lua_pushliteral(nativeContext,"_rpcName"); - lua_pushlstring(nativeContext,rpc.c_str(),rpc.size()); - lua_rawset(nativeContext,-3); - - // - lua_createtable(nativeContext,0,1); - lua_pushliteral(nativeContext,"__call"); - lua_pushlightuserdata(nativeContext, this); - lua_pushcclosure(nativeContext, &Internal::NetBinding__CallRPC,1); - lua_rawset(nativeContext,-3); - - lua_setmetatable(nativeContext,-2); - // - - lua_rawset(nativeContext,tableStackIndex); - // - - m_rpcHelperMap.insert(RPCHelperMap::value_type(rpc,helper)); - } - } - } - - GridMate::ReplicaChunkPtr ScriptNetBindingTable::GetNetworkBinding() - { - m_replicaChunk = GridMate::CreateReplicaChunk(); - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - - return m_replicaChunk; - } - - void ScriptNetBindingTable::SetNetworkBinding(GridMate::ReplicaChunkPtr chunk) - { - m_replicaChunk = chunk; - m_replicaChunk->SetHandler(this); - - if (m_entityScriptContext.HasScriptContext()) - { - AssignDataSets(); - } - } - - void ScriptNetBindingTable::UnbindFromNetwork() - { - if (m_replicaChunk) - { - m_replicaChunk->SetHandler(nullptr); - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - tablePair.second.UnbindFromDataSet(); - } - - m_replicaChunk = nullptr; - } - } - - void ScriptNetBindingTable::OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc) - { - AZ_Error("ScriptComponent",m_replicaChunk != nullptr,"DataSet callback method called without ReplicaChunk present."); - - if (scriptProperty && m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptReplicaChunk = static_cast(m_replicaChunk.get()); - - NetworkedTableValue* tableValue = FindTableValue(scriptProperty->m_name); - - if (tableValue) - { - if (!tableValue->HasDataSet()) - { - scriptReplicaChunk->AssignDataSetForProperty((*tableValue),scriptProperty); - AZ_Error("ScriptComponent",tableValue->HasDataSet(),"Unable to bind received ScriptProperty to DataSet."); - } - else - { - AZ_Error("ScriptComponent",scriptReplicaChunk->SanityCheckDataSet(scriptProperty,tableValue->GetDataSet()),"Mismatch between DataSet being chagned and mapping to dataset index."); - } - - if (tableValue->HasCallback()) - { - tableValue->InvokeCallback(m_entityScriptContext,tc); - } - } - else - { - AZ_Error("ScriptComponent",false,"Receiving update for unknown ScriptProperty."); - } - } - } - - bool ScriptNetBindingTable::OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> params, const GridMate::RpcContext& rpcContext) - { - (void)rpcContext; - - bool canProxyExecute = false; - AZ_Error("ScriptComponent",m_replicaChunk,"Receiving RPC callback with null ReplicaChunk."); - - RPCHelperMap::iterator rpcIter = m_rpcHelperMap.find(functionName); - - if (rpcIter != m_rpcHelperMap.end()) - { - RPCBindingHelper& rpcHelper = rpcIter->second; - - if (m_replicaChunk == nullptr || m_replicaChunk->IsMaster()) - { - canProxyExecute = rpcHelper.InvokeMaster(m_entityScriptContext,params); - } - else - { - // The canProxyExecute return value is meaningless on proxies. - rpcHelper.InvokeProxy(m_entityScriptContext,params); - } - } - - return canProxyExecute; - } - - const AZ::ScriptProperty* ScriptNetBindingTable::FindScriptProperty(const AZStd::string& name) const - { - const NetworkedTableValue* networkedTableValue = FindTableValue(name); - return networkedTableValue ? networkedTableValue->GetShimmedScriptProperty() : nullptr; - } - - void ScriptNetBindingTable::AssignDataSets() - { - if (m_replicaChunk) - { - ScriptComponentReplicaChunk* scriptComponentChunk = static_cast(m_replicaChunk.get()); - - // Going to do this in two passes, first to do all of the forced ones, then all of the arbitrary ones. - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - if (tablePair.second.HasForcedDataSetIndex() && !tablePair.second.HasDataSet()) - { - if (!scriptComponentChunk->AssignDataSet(tablePair.second)) - { - // Remove the forced DataSet index since it was invalid. - // Second pass will assign this an arbitrary one. - tablePair.second.SetForcedDataSetIndex(-1); - } - } - } - - for (NetworkedTableMap::value_type& tablePair : m_networkedTable) - { - // Try to assign everything that doesn't already have a dataset. - if (!tablePair.second.HasDataSet()) - { - scriptComponentChunk->AssignDataSet(tablePair.second); - } - } - } - } - - ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) - { - NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - const ScriptNetBindingTable::NetworkedTableValue* ScriptNetBindingTable::FindTableValue(const AZStd::string& name) const - { - const NetworkedTableValue* retVal = nullptr; - NetworkedTableMap::const_iterator tableIter = m_networkedTable.find(name); - - if (tableIter != m_networkedTable.end()) - { - retVal = &(tableIter->second); - } - - return retVal; - } - - //////////////////////////////// - // ScriptComponentReplicaChunk - //////////////////////////////// - - ScriptComponentReplicaChunk::ScriptComponentReplicaChunk() - : m_scriptRPC("ScriptRPC") - , m_enabledDataSetMask(0) - { - } - - ScriptComponentReplicaChunk::~ScriptComponentReplicaChunk() - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - ScriptPropertyDataSet& dataSet = m_propertyDataSets[i]; - - dataSet.Modify([](AZ::ScriptProperty*& scriptProperty) - { - delete scriptProperty; - scriptProperty = nullptr; - return false; - }); - } - } - - bool ScriptComponentReplicaChunk::IsReplicaMigratable() - { - return true; - } - - AZ::u32 ScriptComponentReplicaChunk::CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) - { - if ((marshalContext.m_marshalFlags & GridMate::ReplicaMarshalFlags::ForceDirty)) - { - return m_enabledDataSetMask; - } - - return GridMate::ReplicaChunkBase::CalculateDirtyDataSetMask(marshalContext); - } - - bool ScriptComponentReplicaChunk::AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper) - { - bool assigned = false; - - if (helper.HasForcedDataSetIndex()) - { - int testIndex = helper.GetForcedDataSetIndex() - 1; - - if (testIndex >= 0 && testIndex < k_maxScriptableDataSets) - { - ScriptPropertyDataSet* testDataSet = &m_propertyDataSets[testIndex]; - - if (!testDataSet->IsReserved()) - { - assigned = true; - helper.RegisterDataSet(testDataSet); - m_enabledDataSetMask |= (1 << testIndex); - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a networked value to a previously used DataSet."); - } - } - else - { - AZ_Error("ScriptComponent",false,"Trying to register a table value to an invalid DataSet index."); - } - } - else - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (!m_propertyDataSets[i].IsReserved()) - { - assigned = true; - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - - AZ_Error("ScriptComponent",assigned, "Trying to create more then %i datasets for a script",k_maxScriptableDataSets); - } - - return assigned; - } - - void ScriptComponentReplicaChunk::AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty) - { - AZ_Error("ScriptComponent",!IsMaster(),"Binding table value to specified DataSet on Master(Master should be making that choice, not responding to a choice)."); - - if (!IsMaster()) - { - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - helper.RegisterDataSet(&m_propertyDataSets[i]); - m_enabledDataSetMask |= (1 << i); - break; - } - } - } - } - - bool ScriptComponentReplicaChunk::SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet) - { - bool isSane = false; - - for (int i=0; i < k_maxScriptableDataSets; ++i) - { - if (m_propertyDataSets[i].Get() == targetProperty) - { - isSane = &(m_propertyDataSets[i]) == assumedDataSet; - break; - } - } - - return isSane; - } -} diff --git a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h b/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h deleted file mode 100644 index eec28b71b0..0000000000 --- a/Code/Framework/AzFramework/AzFramework/Script/ScriptNetBindings.h +++ /dev/null @@ -1,320 +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. -* -*/ -#ifndef AZFRAMEWORK_SCRIPT_NET_BINDINGS_H -#define AZFRAMEWORK_SCRIPT_NET_BINDINGS_H - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace AzFramework -{ - class ScriptPropertyDataSet; - class ScriptComponentReplicaChunk; - - // ScriptNetBindingTable will act as the go between for the ScriptComponent and the Replica's. - // It will also allow for holding of values in the case where you haven't been bound to a replica chunk yet and the - // script tries to interact with something that is networked. - // - // Allows for scripts to be re-used seamlessly in a offline vs online scenario(and support for going from offline to online), - // including RPCs(will alawys call the master version if offline) - class ScriptNetBindingTable - : public GridMate::ReplicaChunkInterface - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptPropertyDataSet; - - // Helper struct to keep track of a a ScriptContext - // and the entityTableReference. Mainly used for - // calling in to functions in LUA where we want - // to push in the table reference as the first parameter - struct EntityScriptContext - { - public: - EntityScriptContext(); - - void Unload(); - - bool HasEntityTableRegistryIndex() const; - int GetEntityTableRegistryIndex() const; - - bool HasScriptContext() const; - AZ::ScriptContext* GetScriptContext() const; - - void ConfigureContext(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - private: - - bool SanityCheckContext() const; - - AZ::ScriptContext* m_scriptContext; - int m_entityTableRegistryIndex; - }; - - class NetworkedTableValue; - friend NetworkedTableValue; - - typedef AZStd::unordered_map NetworkedTableMap; - - class RPCBindingHelper; - friend RPCBindingHelper; - - typedef AZStd::unordered_map RPCHelperMap; - - // Helper class that will wrap up our interactions with the actual stored value - // to hide the general use case of if we are connected to a replica or not. - // - // Additionally this will serve as a holding ground for a 'networked' - // value that doesn't have a dataset. - // - // Lastly holds onto the Callback references. - class NetworkedTableValue - { - public: - AZ_CLASS_ALLOCATOR(NetworkedTableValue, AZ::SystemAllocator, 0); - - NetworkedTableValue(AZ::ScriptProperty* initialValue = nullptr); - ~NetworkedTableValue(); - - void Destroy(); - - // Methods to register this value to a chunk - bool HasDataSet() const; - void RegisterDataSet(ScriptPropertyDataSet* dataSet); - void UnbindFromDataSet(); - ScriptPropertyDataSet* GetDataSet() const; - - // Information kept in order to force these values to use a particular dataset for debugging. - bool HasForcedDataSetIndex() const; - void SetForcedDataSetIndex(int index); - int GetForcedDataSetIndex() const; - - // Callback functions - bool HasCallback() const; - void RegisterCallback(int functionReference); - void ReleaseCallback(AZ::ScriptContext& scriptContext); - void InvokeCallback(EntityScriptContext& scriptContext, const GridMate::TimeContext& timeContext); - - bool AssignValue(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - bool InspectValue(AZ::ScriptContext* scriptContext) const; - - // Methods used for unit tests - const AZ::ScriptProperty* GetShimmedScriptProperty() const { return m_shimmedScriptProperty; } - private: - - // This value will be used if we have a networked property, but don't have a valid chunk yet. - // Works as a temporary store, which will be resolved once we get assigned to a DataSet - AZ::ScriptProperty* m_shimmedScriptProperty; - - // The data set we are bound to - ScriptPropertyDataSet* m_dataSet; - int m_forcedDataSetIndex; - - int m_functionReference; - }; - - // Future thoughts - // - Move the actual RPC meta table creation - // into this guy - class RPCBindingHelper - { - public: - AZ_CLASS_ALLOCATOR(RPCBindingHelper, AZ::SystemAllocator, 0); - - RPCBindingHelper(); - ~RPCBindingHelper(); - - void ReleaseTableIndex(AZ::ScriptContext& scriptContext); - - bool IsValid() const; - - void SetMasterFunction(int masterReference); - bool InvokeMaster(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - void SetProxyFunction(int masterReference); - void InvokeProxy(EntityScriptContext& entityScriptContext, const ScriptRPCMarshaler::Container& params); - - private: - int m_masterReference; - int m_proxyReference; - }; - - public: - AZ_CLASS_ALLOCATOR(ScriptNetBindingTable, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* reflect); - - ScriptNetBindingTable(); - ~ScriptNetBindingTable(); - - void Unload(); - - void CreateNetworkBindingTable(AZ::ScriptContext* scriptContext, int baseTableIndex, int entityTableIndex); - void FinalizeNetworkTable(AZ::ScriptContext* scriptContext, int entityTableRegistryIndex); - - AZ::ScriptContext* GetScriptContext() const; - - bool IsMaster() const; - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - // DataSet Functionality - // - // Called when the script wants to bind a function callback to when - // a value changes - // - // Might change this to just be register DataSet - bool RegisterDataSet(AZ::ScriptDataContext& stackContext, AZ::ScriptProperty* scriptProperty); - - // Called when the script wants to assign a value to the script value - bool AssignTableValue(AZ::ScriptDataContext& stackContext); - - // Called when the script wants to know the value of a script value. - bool InspectTableValue(AZ::ScriptDataContext& stackContext) const; - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - ////////////////////////////////////////////////////////////////////////////////////////////////////// - /// RPC Functionality - void RegisterRPC(AZ::ScriptDataContext& rpcTableContext, const AZStd::string& rpcName, int elementIndex, int tableStackIndex); - bool InvokeRPC(AZ::ScriptDataContext& stackContext); - ////////////////////////////////////////////////////////////////////////////////////////////////////// - - // Netbinding Interface duplication here to be called from the ScriptComponent - GridMate::ReplicaChunkPtr GetNetworkBinding(); - void SetNetworkBinding(GridMate::ReplicaChunkPtr chunk); - void UnbindFromNetwork(); - - void OnPropertyUpdate(AZ::ScriptProperty*const& scriptProperty, const GridMate::TimeContext& tc); - bool OnInvokeRPC(AZStd::string functionName, AZStd::vector< AZ::ScriptProperty*> properties, const GridMate::RpcContext& rpcContext); - - // Methods used for unit tests - const AZ::ScriptProperty* FindScriptProperty(const AZStd::string& name) const; - - - private: - - void RegisterMetaTableCache(); - - template - AZ::ScriptPropertyTable* ConvertPropertyArrayToTable(PropertyArrayType* arrayProperty) - { - AZ::ScriptPropertyTable* scriptPropertyTable = aznew AZ::ScriptPropertyTable(arrayProperty->m_name.c_str()); - - PropertyType propertyType; - - for (unsigned int i=0; i < arrayProperty->m_values.size(); ++i) - { - propertyType.m_value = arrayProperty->m_values[i]; - - // Offset by 1 to deal with lua 1 indexing. - // Table will make a clone of our object. - scriptPropertyTable->SetTableValue(i+1, &propertyType); - } - - return scriptPropertyTable; - } - - void AssignDataSets(); - - NetworkedTableValue* FindTableValue(const AZStd::string& name); - const NetworkedTableValue* FindTableValue(const AZStd::string& name) const; - - EntityScriptContext m_entityScriptContext; - - GridMate::ReplicaChunkPtr m_replicaChunk; - - NetworkedTableMap m_networkedTable; - RPCHelperMap m_rpcHelperMap; - }; - - // Typedeffing out the RPC and DataSet definitions. - typedef GridMate::Rpc< GridMate::RpcArg< AZStd::string >, GridMate::RpcArg< ScriptRPCMarshaler::Container, ScriptRPCMarshaler > >::BindInterface ScriptPropertyRPC; - typedef GridMate::DataSet::BindInterface ScriptPropertyDataSetType; - - class ScriptComponentReplicaChunk; - - // Specialized DataSet used by the ScriptProperties, just to add some wrapped around functionality - // and to allow me to manipulate the DataSet throttler in order to properly manage a dirty flag - class ScriptPropertyDataSet - : public ScriptPropertyDataSetType - , public AZ::ScriptPropertyWatcherBus::Handler - , public AZ::ScriptPropertyWatcher - { - private: - friend class ScriptComponentReplicaChunk; - friend class ScriptNetBindingTable::NetworkedTableValue; - - const char* GetDataSetName(); - - public: - ScriptPropertyDataSet(); - ~ScriptPropertyDataSet(); - bool IsReserved() const; - - bool UpdateScriptProperty(AZ::ScriptDataContext& scriptDataContext, const AZStd::string& propertyName); - void SetScriptProperty(AZ::ScriptProperty* scriptProperty); - - void OnObjectModified() override; - - private: - void Reserve(ScriptNetBindingTable::NetworkedTableValue* reserver); - void Release(ScriptNetBindingTable::NetworkedTableValue* reserver); - - ScriptNetBindingTable::NetworkedTableValue* m_reserver; - }; - - // The actual ReplicaChunk that the script will use - class ScriptComponentReplicaChunk - : public GridMate::ReplicaChunkBase - { - public: - AZ_CLASS_ALLOCATOR(ScriptComponentReplicaChunk, AZ::SystemAllocator,0); - static const int k_maxScriptableDataSets = GM_MAX_DATASETS_IN_CHUNK; - - static const char* GetChunkName() { return "ScriptComponentReplicaChunk"; } - - // Might want to add some type of comment field into the various fields so this can be properly parsed - // and determined what we are actually sending. - ScriptComponentReplicaChunk(); - ~ScriptComponentReplicaChunk(); - - bool IsReplicaMigratable() override; - - AZ::u32 CalculateDirtyDataSetMask(GridMate::MarshalContext& marshalContext) override; - - // Called from the Master, will assign the table value to the DataSet specified by the helper. - bool AssignDataSet(ScriptNetBindingTable::NetworkedTableValue& helper); - - // Called from teh Proxy. Will Assign the TableValue to the DataSet that contains the target property - void AssignDataSetForProperty(ScriptNetBindingTable::NetworkedTableValue& helper, AZ::ScriptProperty* targetProperty); - - // Only called inside of an assert, checks that the DataSet that the targetProperty is in is the same as the assumedDataSet - // Used to confirm that we don't get a confusion between master/proxy about which ScriptProperty is assigned to which DataSet. - bool SanityCheckDataSet(AZ::ScriptProperty* targetProperty, ScriptPropertyDataSet* assumedDataSet); - - ScriptPropertyRPC m_scriptRPC; - - private: - AZ::u32 m_enabledDataSetMask; - ScriptPropertyDataSet m_propertyDataSets[k_maxScriptableDataSets]; - }; -} - -#endif diff --git a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp index e44185bd33..d3ba48d587 100644 --- a/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp +++ b/Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp @@ -177,7 +177,7 @@ namespace AzFramework Neighborhood::NeighborReplicaPtr replicaChunk = GridMate::CreateReplicaChunk(session->GetMyMember()->GetId().Compact(), m_component->m_settings->m_persistentName.c_str(), Neighborhood::NEIGHBOR_CAP_LUA_VM | Neighborhood::NEIGHBOR_CAP_LUA_DEBUGGER); replicaChunk->SetDisplayName(m_component->m_settings->m_persistentName.c_str()); replica->AttachReplicaChunk(replicaChunk); - session->GetReplicaMgr()->AddMaster(replica); + session->GetReplicaMgr()->AddPrimary(replica); } } diff --git a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake index 1b1cd49aa7..48b0202a5b 100644 --- a/Code/Framework/AzFramework/AzFramework/azframework_files.cmake +++ b/Code/Framework/AzFramework/AzFramework/azframework_files.cmake @@ -161,26 +161,6 @@ set(FILES Metrics/MetricsPlainTextNameRegistration.h Network/AssetProcessorConnection.cpp Network/AssetProcessorConnection.h - Network/DynamicSerializableFieldMarshaler.h - Network/EntityIdMarshaler.h - Network/InterestManagerComponent.h - Network/InterestManagerComponent.cpp - Network/NetBindable.h - Network/NetBindable.cpp - Network/NetBindingEventsBus.h - Network/NetBindingHandlerBus.h - Network/NetBindingSystemBus.h - Network/NetBindingComponent.h - Network/NetBindingComponent.cpp - Network/NetBindingComponentChunk.h - Network/NetBindingComponentChunk.cpp - Network/NetBindingSystemImpl.h - Network/NetBindingSystemImpl.cpp - Network/NetBindingSystemComponent.h - Network/NetBindingSystemComponent.cpp - Network/NetworkContext.h - Network/NetworkContext.cpp - Network/NetSystemBus.h Network/SocketConnection.cpp Network/SocketConnection.h Logging/LogFile.cpp @@ -203,10 +183,6 @@ set(FILES Script/ScriptDebugAgentBus.h Script/ScriptDebugMsgReflection.cpp Script/ScriptDebugMsgReflection.h - Script/ScriptMarshal.h - Script/ScriptMarshal.cpp - Script/ScriptNetBindings.h - Script/ScriptNetBindings.cpp Script/ScriptRemoteDebugging.cpp Script/ScriptRemoteDebugging.h StreamingInstall/StreamingInstall.h @@ -279,6 +255,7 @@ set(FILES Physics/ClassConverters.cpp Physics/ClassConverters.h Physics/MaterialBus.h + Physics/WindBus.h Process/ProcessCommunicator.cpp Process/ProcessCommunicator.h Process/ProcessWatcher.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp index ac5f1136f5..70cad69268 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ToolsComponents/TransformComponent.cpp @@ -1287,7 +1287,6 @@ namespace AzToolsFramework Field("Cached World Transform Parent", &TransformComponent::m_cachedWorldTransformParent)-> Field("Parent Activation Transform Mode", &TransformComponent::m_parentActivationTransformMode)-> Field("IsStatic", &TransformComponent::m_isStatic)-> - Field("Sync Enabled", &TransformComponent::m_netSyncEnabled)-> Field("InterpolatePosition", &TransformComponent::m_interpolatePosition)-> Field("InterpolateRotation", &TransformComponent::m_interpolateRotation)-> Version(9, &Internal::TransformComponentDataConverter); @@ -1322,21 +1321,7 @@ namespace AzToolsFramework Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)-> DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_cachedWorldTransform, "Cached World Transform", "")-> Attribute(AZ::Edit::Attributes::SliceFlags, AZ::Edit::SliceFlags::NotPushable)-> - Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)-> - - ClassElement(AZ::Edit::ClassElements::Group, "Network Sync")-> - Attribute(AZ::Edit::Attributes::AutoExpand, true)-> - - DataElement(AZ::Edit::UIHandlers::Default, &TransformComponent::m_netSyncEnabled, "Sync to replicas", "Sync to network replicas.")-> - DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_interpolatePosition, - "Position Interpolation", "Enable local interpolation of position.")-> - EnumAttribute(AZ::InterpolationMode::NoInterpolation, "None")-> - EnumAttribute(AZ::InterpolationMode::LinearInterpolation, "Linear")-> - - DataElement(AZ::Edit::UIHandlers::ComboBox, &TransformComponent::m_interpolateRotation, - "Rotation Interpolation", "Enable local interpolation of rotation.")-> - EnumAttribute(AZ::InterpolationMode::NoInterpolation, "None")-> - EnumAttribute(AZ::InterpolationMode::LinearInterpolation, "Linear"); + Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide); ptrEdit->Class("Values", "XYZ PYR")-> DataElement(AZ::Edit::UIHandlers::Default, &EditorTransform::m_translate, "Translate", "Local Position (Relative to parent) in meters.")-> diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp index 9388f3f5f0..c6450d03c7 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/ViewportSelection/EditorTransformComponentSelection.cpp @@ -13,6 +13,9 @@ #include "EditorTransformComponentSelection.h" #include +#include +#include +#include #include #include #include diff --git a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp index e3b474ba5d..380739bab1 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/SecureSocketDriver.cpp @@ -1486,7 +1486,7 @@ namespace GridMate // Only support a single cipher suite in OpenSSL that supports: // - // ECDHE Master key exchange using ephemeral elliptic curve diffie-hellman. + // ECDHE Key exchange using ephemeral elliptic curve diffie-hellman. // RSA Authentication (public and private key) used to sign ECDHE parameters and can be checked against a CA. // AES256 AES cipher for symmetric key encryption using a 256-bit key. // GCM Mode of operation for symmetric key encryption. diff --git a/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp b/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp index 9e59496ed1..30c2c63ed9 100644 --- a/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp +++ b/Code/Framework/GridMate/GridMate/Carrier/StreamSecureSocketDriver.cpp @@ -97,7 +97,7 @@ namespace GridMate // Only support a single cipher suite in OpenSSL that supports: // - // ECDHE Master key exchange using ephemeral elliptic curve diffie-hellman. + // ECDHE Key exchange using ephemeral elliptic curve diffie-hellman. // RSA Authentication (public and private key) used to sign ECDHE parameters and can be checked against a CA. // AES256 AES cipher for symmetric key encryption using a 256-bit key. // GCM Mode of operation for symmetric key encryption. diff --git a/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp b/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp index 614c50a7e0..fb6a6fe5cd 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/DataSet.cpp @@ -52,6 +52,6 @@ namespace GridMate bool DataSetBase::CanSet() const { - return m_replicaChunk ? m_replicaChunk->IsMaster() : true; + return m_replicaChunk ? m_replicaChunk->IsPrimary() : true; } } diff --git a/Code/Framework/GridMate/GridMate/Replica/DataSet.h b/Code/Framework/GridMate/GridMate/Replica/DataSet.h index f91a86dcec..61ff75516b 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DataSet.h +++ b/Code/Framework/GridMate/GridMate/Replica/DataSet.h @@ -43,7 +43,7 @@ namespace GridMate struct DataSetDefaultTraits { /** - * \brief Should a change in DataSet value invoke a callback on a master replica chunk? + * \brief Should a change in DataSet value invoke a callback on a primary replica chunk? * * By default, DataSet::BindInterface only invokes on client/non-authoritative replica chunks. * This switch enables the callback on server/authoritative replica chunks. @@ -55,7 +55,7 @@ namespace GridMate }; /** - * \brief Turns on DataSet callbacks to be invoked on the master replica as well as client replicas. + * \brief Turns on DataSet callbacks to be invoked on the primary replica as well as client replicas. */ struct DataSetInvokeEverywhereTraits : DataSetDefaultTraits { @@ -200,7 +200,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(const DataType& v) @@ -214,7 +214,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(DataType&& v) @@ -228,7 +228,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ template @@ -243,7 +243,7 @@ namespace GridMate } /** - Modify the DataSet directly without copying it. Call this on the Master node, + Modify the DataSet directly without copying it. Call this on the Primary node, passing in a function object that takes the value by reference, optionally modifies the data, and returns true if the data was changed. **/ diff --git a/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h b/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h index cc19c2336b..8d88635c07 100644 --- a/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h +++ b/Code/Framework/GridMate/GridMate/Replica/DeltaCompressedDataSet.h @@ -159,7 +159,7 @@ namespace GridMate } /** - Modify the DataSet. Call this on the Master node to change the data, + Modify the DataSet. Call this on the Primary node to change the data, which will be propagated to all proxies. **/ void Set(const FieldType& v) @@ -201,7 +201,7 @@ namespace GridMate private: DataSet m_absolutePortion; DataSet m_relativePortion; - FieldType m_combinedValue; // the latest value on either master or proxy + FieldType m_combinedValue; // the latest value on either primary or proxy }; //----------------------------------------------------------------------------- diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp index 1a35fd1893..75f4c8bdd2 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/BitmaskInterestHandler.cpp @@ -366,7 +366,7 @@ namespace GridMate auto replica = Replica::CreateReplica("BitmaskInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void BitmaskInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp index 770dcd4f1f..ff1a29a917 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/InterestManager.cpp @@ -206,7 +206,7 @@ namespace GridMate return false; } - if (replica->IsMaster()) // own the replica? + if (replica->IsPrimary()) // own the replica? { return true; } diff --git a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp index 4e3c2c77a4..13a0151bc7 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Interest/ProximityInterestHandler.cpp @@ -508,7 +508,7 @@ namespace GridMate auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) diff --git a/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp b/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp index 48fbfe5289..a1150a198a 100644 --- a/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/MigrationSequence.cpp @@ -26,7 +26,7 @@ namespace GridMate m_replicaMgr = replica->GetReplicaManager(); - if (replica->IsMaster() && newOwnerId != m_replicaMgr->GetLocalPeerId()) + if (replica->IsPrimary() && newOwnerId != m_replicaMgr->GetLocalPeerId()) { m_sm.SetStateHandler(AZ_HSM_STATE_NAME(MST_TOP), AZ::HSM::StateHandler(this, &MigrationSequence::DefaultHandler), AZ::HSM::InvalidStateId, MST_MIGRATING); } @@ -312,7 +312,7 @@ namespace GridMate return true; case ME_MODIFY_NEW_OWNER: m_newOwnerId = *static_cast(event.userData); - if (m_replica->IsMaster() && m_newOwnerId != m_replicaMgr->m_self.GetId()) + if (m_replica->IsPrimary() && m_newOwnerId != m_replicaMgr->m_self.GetId()) { sm.Transition(MST_MIGRATING); } diff --git a/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h b/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h index 98494267ad..4256dd978b 100644 --- a/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h +++ b/Code/Framework/GridMate/GridMate/Replica/RemoteProcedureCall.h @@ -370,8 +370,8 @@ namespace GridMate PeerId sourcePeerId = GetSourcePeerId(); bool shouldQueue = true; bool processed = false; - bool isMaster = m_replicaChunk->IsMaster(); - if (isMaster) + bool isPrimary = m_replicaChunk->IsPrimary(); + if (isPrimary) { // We are authoritative so execute the RPC immediately, forwarding the args along RpcRequest localRequest(this, rc.m_realTime, rc.m_realTime, rc.m_localTime); @@ -385,7 +385,7 @@ namespace GridMate if (shouldQueue) { TypeTuple* storage = aznew TypeTuple(this, RpcContext(rc.m_realTime, rc.m_realTime, rc.m_localTime, sourcePeerId), AZStd::forward(args) ...); - storage->m_authoritative = isMaster; + storage->m_authoritative = isPrimary; storage->m_processed = processed; storage->m_reliable = Traits::s_isReliable; OnRpcRequest(storage); diff --git a/Code/Framework/GridMate/GridMate/Replica/Replica.cpp b/Code/Framework/GridMate/GridMate/Replica/Replica.cpp index 483e523e05..c0a92de0d8 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Replica.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Replica.cpp @@ -106,7 +106,7 @@ namespace GridMate //----------------------------------------------------------------------------- void Replica::Destroy() { - AZ_Assert(IsMaster(), "We don't own replica 0x%x!", GetRepId()); + AZ_Assert(IsPrimary(), "We don't own replica 0x%x!", GetRepId()); if (m_manager) { m_manager->Destroy(this); @@ -327,7 +327,7 @@ namespace GridMate if (IsActive()) { - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(Debug::ReplicaDrillerBus, OnRequestReplicaChangeOwnership, this, requestor); diff --git a/Code/Framework/GridMate/GridMate/Replica/Replica.h b/Code/Framework/GridMate/GridMate/Replica/Replica.h index fb630ac1a4..5291a7f143 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Replica.h +++ b/Code/Framework/GridMate/GridMate/Replica/Replica.h @@ -68,7 +68,7 @@ namespace GridMate Rep_ManagedAlloc = 1 << 1, Rep_CanMigrate = 1 << 2, Rep_New = 1 << 3, - Rep_Master = 1 << 4, + Rep_Primary = 1 << 4, Rep_Active = 1 << 6, Rep_ChangedOwner = 1 << 7, Rep_SuspendDownstream = 1 << 8, @@ -85,7 +85,7 @@ namespace GridMate void Destroy(); - void UpdateReplica(const ReplicaContext& rc); // Called when updating replica master from source + void UpdateReplica(const ReplicaContext& rc); // Called when updating replica primary from source void UpdateFromReplica(const ReplicaContext& rc); // Called when updating game with replica info bool AcceptChangeOwnership(PeerId requestor, const ReplicaContext& rc); // Return true to accept the transfer void OnActivate(const ReplicaContext& rc); @@ -112,8 +112,8 @@ namespace GridMate void RequestChangeOwnership(PeerId newOwner = InvalidReplicaPeerId); // If newOwner is not specified we assume it should be the local peer - bool IsMaster() const { return !IsActive() || !!(m_flags & Rep_Master); } - bool IsProxy() const { return !IsMaster(); } + bool IsPrimary() const { return !IsActive() || !!(m_flags & Rep_Primary); } + bool IsProxy() const { return !IsPrimary(); } bool IsNew() const { return !!(m_flags & Rep_New); } bool IsNewOwner() const { return !!(m_flags & Rep_ChangedOwner); } bool IsActive() const { return !!(m_flags & Rep_Active); } @@ -170,7 +170,7 @@ namespace GridMate void MarkRPCsAsRelayed(); - void SetMaster(bool isMaster) { m_flags = isMaster ? m_flags | Rep_Master : m_flags & ~Rep_Master; } + void SetPrimary(bool isPrimary) { m_flags = isPrimary ? m_flags | Rep_Primary : m_flags & ~Rep_Primary; } void SetNew() { m_flags |= Rep_New; } void SetRepId(ReplicaId id); void SetMigratable(bool migratable); diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp index 087f5f3273..adcff38190 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.cpp @@ -125,18 +125,18 @@ namespace GridMate return false; } //----------------------------------------------------------------------------- - bool ReplicaChunkBase::IsMaster() const + bool ReplicaChunkBase::IsPrimary() const { if (m_replica) { - return m_replica->IsMaster(); + return m_replica->IsPrimary(); } return true; } //----------------------------------------------------------------------------- bool ReplicaChunkBase::IsProxy() const { - return !IsMaster(); + return !IsPrimary(); } //----------------------------------------------------------------------------- bool ReplicaChunkBase::IsDirty(AZ::u32 marshalFlags) const @@ -398,8 +398,8 @@ namespace GridMate { if (mc.m_peer != m_replica->m_upstreamHop) { - AZ_TracePrintf("GridMate", "Received dataset updates for replica id %08x(%s) from unexpected peer.", GetReplicaId(), IsActive() && IsMaster() ? "master" : "proxy"); - if (IsMaster()) + AZ_TracePrintf("GridMate", "Received dataset updates for replica id %08x(%s) from unexpected peer.", GetReplicaId(), IsActive() && IsPrimary() ? "primary" : "proxy"); + if (IsPrimary()) { mc.m_iBuf->Skip(mc.m_iBuf->Left()); return; @@ -547,7 +547,7 @@ namespace GridMate AZ_Assert(false, "Discarding non-authoritative RPC <%s> because s_allowNonAuthoritativeRequests trait is disabled!", GetDescriptor()->GetRpcName(this, rpc)); isRpcValid = false; } - if (!rpc->IsAllowNonAuthoritativeRequestsRelay() && !IsMaster()) + if (!rpc->IsAllowNonAuthoritativeRequestsRelay() && !IsPrimary()) { AZ_Assert(false, "Discarding non-authoritative RPC <%s> because s_allowNonAuthoritativeRequestRelay trait is disabled!", GetDescriptor()->GetRpcName(this, rpc)); isRpcValid = false; @@ -639,19 +639,19 @@ namespace GridMate for (RPCQueue::iterator iRPC = m_rpcQueue.begin(); iRPC != m_rpcQueue.end(); ) { Internal::RpcRequest* request = *iRPC; - bool isMaster = IsMaster(); // need to do this check after each RPC because ownership may change + bool isPrimary = IsPrimary(); // need to do this check after each RPC because ownership may change if (!m_replica->IsActive()) // this can happen if replica was deactivated within a previous RPC call { request->m_relayed = true; } - else if (!request->m_processed && (isMaster || request->m_authoritative)) + else if (!request->m_processed && (isPrimary || request->m_authoritative)) { request->m_realTime = rc.m_realTime; request->m_localTime = rc.m_localTime; bool ret = request->m_rpc->Invoke(request); request->m_processed = true; - if (isMaster) + if (isPrimary) { if (ret) { diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h index 7cfff0fe26..50b6bb8584 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaChunk.h @@ -45,17 +45,17 @@ namespace GridMate /** A single unit of network functionality A ReplicaChunk is a user extendable network object. One or more ReplicaChunks can be owned by a Replica, which is both a container and manager for them. A replica is owned - by a Master, and is propagated to other network nodes, who interact with is as a Proxy. + by a Primary, and is propagated to other network nodes, who interact with is as a Proxy. The data a ReplicaChunk contains should generally be related to the other data stored within it. Since multiple chunks can be attached to a Replica, unrelated data can simply be stored in other chunks on the same Replica. A ReplicaChunk has two primary ways to interact with it: DataSets and Remote Procedure Calls (RPCs). - DataSets store arbitrary data, which only the Master is able to modify. Any changes are + DataSets store arbitrary data, which only the Primary is able to modify. Any changes are propagated to the Proxy ReplicaChunks on the other nodes. RPCs are methods that can be executed on a remote node. They are first invoked on the - Master, who then decides if the invocation should be propagated to the Proxies. + Primary, who then decides if the invocation should be propagated to the Proxies. ReplicaChunks can be created by inheriting from the class and registered by calling ReplicaChunkDescriptorTable::RegisterChunkType() to create the factory required by @@ -107,7 +107,7 @@ namespace GridMate PeerId GetPeerId() const; virtual ReplicaManager* GetReplicaManager(); bool IsActive() const; - bool IsMaster() const; + bool IsPrimary() const; bool IsProxy() const; virtual void OnAttachedToReplica(Replica* replica) { (void) replica; } @@ -191,7 +191,7 @@ namespace GridMate void AddDataSetEvent(DataSetBase* dataset); // Called to enqueue a user event handler for a modified DataSet on a proxy node - void SignalDataSetChanged(const DataSetBase& dataset); // Called when the DataSet changes on the master node + void SignalDataSetChanged(const DataSetBase& dataset); // Called when the DataSet changes on the primary node void EnqueueMarshalTask(); diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h index 09b454a03e..14e70a3213 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaDrillerEvents.h @@ -62,7 +62,7 @@ namespace GridMate //! Called when an ownership transfer request is received. virtual void OnRequestReplicaChangeOwnership(Replica* replica, PeerId requestor) { (void)replica; (void)requestor; } //! Called when a replica changes ownership, not necessarily to or from the local node. - virtual void OnReplicaChangeOwnership(Replica* replica, bool wasMaster) { (void)replica; (void)wasMaster; } + virtual void OnReplicaChangeOwnership(Replica* replica, bool wasPrimary) { (void)replica; (void)wasPrimary; } //! Called when a chunk has been created. It doesn't mean it will be added to the system. //! Object will be partially constructed at this point if you inherit from ReplicaChunk @@ -91,9 +91,9 @@ namespace GridMate //! Called when data is received for a dataset. virtual void OnReceiveDataSet(ReplicaChunkBase* chunk, AZ::u32 chunkIndex, DataSetBase* dataSet, PeerId from, PeerId to, const void* data, size_t len) { (void)chunk; (void)chunkIndex; (void)dataSet; (void)from; (void)to; (void)data; (void)len; } - //! Called when an rpc request is received. RpcRequest pointer will be null if rpc is called on master replica. + //! Called when an rpc request is received. RpcRequest pointer will be null if rpc is called on primary replica. virtual void OnRequestRpc(ReplicaChunkBase* chunk, Internal::RpcRequest* rpc) { (void)chunk; (void)rpc; } - //! Called when an rpc is invoked. RpcRequest pointer will be null if rpc is called on master replica. + //! Called when an rpc is invoked. RpcRequest pointer will be null if rpc is called on primary replica. virtual void OnInvokeRpc(ReplicaChunkBase* chunk, Internal::RpcRequest* rpc) { (void)chunk; (void)rpc; } //! Called every time an rpc is sent to a peer. virtual void OnSendRpc(ReplicaChunkBase* chunk, AZ::u32 chunkIndex, Internal::RpcRequest* rpc, PeerId from, PeerId to, const void* data, size_t len) { (void)chunk; (void)chunkIndex; (void)rpc; (void)from; (void)to; (void)data; (void)len; } diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp index 32a941ef4a..78d6f260db 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.cpp @@ -386,7 +386,7 @@ namespace GridMate replica->SetMigratable(true); // register global session info - // this one is kind of special so don't go through AddMaster() + // this one is kind of special so don't go through AddPrimary() ReplicaContext rc(this, GetTime(), &m_self); replica->m_createTime = rc.m_realTime; replica->SetRepId(RepId_SessionInfo); @@ -405,7 +405,7 @@ namespace GridMate else { // take over ownership of the session info - AZ_Assert(!m_sessionInfo->IsMaster(), "We just became host but we were already the owner of sessionInfo!"); + AZ_Assert(!m_sessionInfo->IsPrimary(), "We just became host but we were already the owner of sessionInfo!"); AZ_Assert(m_sessionInfo->m_pHostPeer->IsOrphan(), "We can't be promoted if we are still connected to the host!"); m_sessionInfo->m_pHostPeer->Remove(m_sessionInfo->GetReplica()); m_self.Add(m_sessionInfo->GetReplica()); @@ -903,7 +903,7 @@ namespace GridMate ReplicaContext rc(this, GetTime()); for (auto& replicaObject : m_self.m_objectsTimeSort) { - if (replicaObject.m_replica->IsMaster()) + if (replicaObject.m_replica->IsPrimary()) { replicaObject.m_replica->UpdateReplica(rc); } @@ -1357,11 +1357,11 @@ namespace GridMate m_flags &= ~Rm_Processing; } //----------------------------------------------------------------------------- - void ReplicaManager::RegisterReplica(const ReplicaPtr& pReplica, bool isMaster, ReplicaContext& rc) + void ReplicaManager::RegisterReplica(const ReplicaPtr& pReplica, bool isPrimary, ReplicaContext& rc) { AZ_Assert((pReplica->m_flags & ~Replica::Rep_Traits) == 0, "This replica is not clean, flags=0x%x, rpcs=%d!", pReplica->m_flags); AZ_Assert(pReplica->GetRepId() != InvalidReplicaId, "You should set the replica ID before you register it!"); - pReplica->SetMaster(isMaster); + pReplica->SetPrimary(isPrimary); pReplica->SetNew(); auto it = m_replicas.insert(AZStd::make_pair(pReplica->GetRepId(), pReplica)); // register with lookup table (void)it; @@ -1371,21 +1371,21 @@ namespace GridMate OnReplicaChanged(pReplica); } //----------------------------------------------------------------------------- - ReplicaId ReplicaManager::AddMaster(const ReplicaPtr& pMaster) + ReplicaId ReplicaManager::AddPrimary(const ReplicaPtr& pPrimary) { AZ_Assert(IsReady(), "ReplicaManager is not ready!"); - AZ_Assert(pMaster, "Attempting to register NULL replica!"); + AZ_Assert(pPrimary, "Attempting to register NULL replica!"); ReplicaId newId = m_localIdBlocks.Alloc(); ReplicaContext rc(this, GetTime(), &m_self); - pMaster->m_createTime = rc.m_realTime; - pMaster->SetRepId(newId); - m_self.Add(pMaster.get()); - AZStd::static_pointer_cast(pMaster->m_replicaStatus)->m_ownerSeq.Set(1); - pMaster->InitReplica(this); - RegisterReplica(pMaster, true, rc); + pPrimary->m_createTime = rc.m_realTime; + pPrimary->SetRepId(newId); + m_self.Add(pPrimary.get()); + AZStd::static_pointer_cast(pPrimary->m_replicaStatus)->m_ownerSeq.Set(1); + pPrimary->InitReplica(this); + RegisterReplica(pPrimary, true, rc); - //AZ_TracePrintf("GridMate", "Peer 0x%x: Added replica master 0x%x.\n", - // GetLocalPeerId(), pMaster->GetRepId()); + //AZ_TracePrintf("GridMate", "Peer 0x%x: Added replica primary 0x%x.\n", + // GetLocalPeerId(), pPrimary->GetRepId()); return newId; } @@ -1458,9 +1458,9 @@ namespace GridMate continue; } - ReplicaPeer* source = replica->IsMaster() ? &m_self : replica->m_upstreamHop; + ReplicaPeer* source = replica->IsPrimary() ? &m_self : replica->m_upstreamHop; - if (replica->IsMaster() + if (replica->IsPrimary() || (IsSyncHost() && source->GetId() != target->GetId() && !(source->GetMode() == Mode_Peer && target->GetMode() == Mode_Peer))) { ReplicaTarget::AddReplicaTarget(target, replica.get()); @@ -1471,7 +1471,7 @@ namespace GridMate else { // Replica might've changed owner -> we need to update its targets accordingly - ReplicaPeer* source = replica->IsMaster() ? &m_self : replica->m_upstreamHop; + ReplicaPeer* source = replica->IsPrimary() ? &m_self : replica->m_upstreamHop; for (auto it = replica->m_targets.begin(); it != replica->m_targets.end(); ) { @@ -1652,14 +1652,14 @@ namespace GridMate } } //----------------------------------------------------------------------------- - void ReplicaManager::ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isMaster) + void ReplicaManager::ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isPrimary) { - bool wasMaster = replica->IsMaster(); - if (wasMaster != isMaster) // wasMaster == isMaster can happen when host's replica is moved to client, and client confirms with Cmd_NewOwner + bool wasPrimary = replica->IsPrimary(); + if (wasPrimary != isPrimary) // wasPrimary == isPrimary can happen when host's replica is moved to client, and client confirms with Cmd_NewOwner { - replica->SetMaster(isMaster); + replica->SetPrimary(isPrimary); replica->OnChangeOwnership(rc); - EBUS_EVENT(Debug::ReplicaDrillerBus, OnReplicaChangeOwnership, replica.get(), wasMaster); + EBUS_EVENT(Debug::ReplicaDrillerBus, OnReplicaChangeOwnership, replica.get(), wasPrimary); } } //----------------------------------------------------------------------------- diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h index 55b8551441..00de7e9e11 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaMgr.h @@ -190,7 +190,7 @@ namespace GridMate //----------------------------------------------------------------------------- struct ReplicaMgrDesc { - // Single-master roles that replica managers can have + // Single-primary roles that replica managers can have enum Roles { Role_SyncHost = 1 << 0, @@ -421,13 +421,13 @@ namespace GridMate size_t ReleaseIdBlock(PeerId requestor); void _Unmarshal(ReadBuffer& rb, ReplicaPeer* from); - void RegisterReplica(const ReplicaPtr& pReplica, bool isMaster, ReplicaContext& rc); + void RegisterReplica(const ReplicaPtr& pReplica, bool isPrimary, ReplicaContext& rc); void UnregisterReplica(const ReplicaPtr& replica, const ReplicaContext& rc); void RemoveReplicaFromDownstream(const ReplicaPtr& replica, const ReplicaContext& rc); void MigrateReplica(ReplicaPtr replica, PeerId newOwnerId); void AnnounceReplicaMigrated(ReplicaId replicaId, PeerId newOwnerId); void OnReplicaMigrated(ReplicaPtr replica, bool isOwner, const ReplicaContext& rc); - void ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isMaster); + void ChangeReplicaOwnership(ReplicaPtr replica, const ReplicaContext& rc, bool isPrimary); void AckUpstreamSuspended(ReplicaId replicaId, PeerId sendTo, AZ::u32 requestTime); void OnAckUpstreamSuspended(ReplicaId replicaId, PeerId from, AZ::u32 requestTime); void AckDownstream(ReplicaId replicaId, PeerId sendTo, AZ::u32 requestTime); @@ -595,7 +595,7 @@ namespace GridMate * Replicas */ virtual ReplicaPtr FindReplica(ReplicaId replicaId); - ReplicaId AddMaster(const ReplicaPtr& pMaster); + ReplicaId AddPrimary(const ReplicaPtr& pPrimary); /* * Tasks diff --git a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h index 7e72dbab63..f3afb7747d 100644 --- a/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h +++ b/Code/Framework/GridMate/GridMate/Replica/ReplicaStatus.h @@ -50,10 +50,10 @@ namespace GridMate //! Called on the originator node to request replica migration. Rpc >::BindInterface RequestOwnership; - //! Called by the master to suspend upstream requests during replica migration. + //! Called by the primary to suspend upstream requests during replica migration. Rpc, RpcArg >::BindInterface MigrationSuspendUpstream; - //! Called by the master to signal downstream flush during replica migration. + //! Called by the primary to signal downstream flush during replica migration. Rpc, RpcArg >::BindInterface MigrationRequestDownstreamAck; struct ReplicaOptions diff --git a/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp b/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp index cbaf97ad1d..944524ed2f 100644 --- a/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/SystemReplicas.cpp @@ -84,7 +84,7 @@ namespace GridMate // on activation of this replica, create our PeerInfo replica Replica* peerReplica = Replica::CreateReplica("PeerInfo"); CreateAndAttachReplicaChunk(peerReplica); - rc.m_rm->AddMaster(peerReplica); + rc.m_rm->AddPrimary(peerReplica); } //----------------------------------------------------------------------------- void SessionInfo::OnReplicaDeactivate(const ReplicaContext& rc) @@ -132,7 +132,7 @@ namespace GridMate (void)rc; if (m_pMgr->IsSyncHost()) { - AZ_Assert(IsMaster(), "The host should always own sessionInfo!!!"); + AZ_Assert(IsPrimary(), "The host should always own sessionInfo!!!"); AZ_Assert(m_pendingPeerReports.find(peerId) == m_pendingPeerReports.end(), "We are already waiting for reports for peer 0x%8x!", peerId); vector peers; @@ -205,7 +205,7 @@ namespace GridMate //----------------------------------------------------------------------------- void PeerReplica::OnReplicaActivate(const ReplicaContext& rc) { - if (IsMaster()) + if (IsPrimary()) { m_peerId.Set(rc.m_rm->GetLocalPeerId()); } diff --git a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp index e295e74556..37c0c1d8c4 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp +++ b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaMarshalTasks.cpp @@ -294,7 +294,7 @@ namespace GridMate //----------------------------------------------------------------------------- ReplicaTask::TaskStatus ReplicaMarshalZombieTask::Run(const RunContext& context) { - if (m_replica->IsMaster() || context.m_replicaManager->IsSyncHost()) + if (m_replica->IsPrimary() || context.m_replicaManager->IsSyncHost()) { m_replica->PrepareData(context.m_replicaManager->GetGridMate()->GetDefaultEndianType(), // A zombie task occurs right before replica gets removed, by design it needs to set all properties one last time. diff --git a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h index 7d9d7e90fe..61e11ed56d 100644 --- a/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h +++ b/Code/Framework/GridMate/GridMate/Replica/Tasks/ReplicaUpdateTasks.h @@ -35,7 +35,7 @@ namespace GridMate }; /** - * Task to update master & proxy replicas. + * Task to update primary & proxy replicas. * Processes RPCs and calls replicas UpdateFromReplica. Will complete immediately if no RPCs * left queued after processing, otherweise will be repeated next update tick. * Initiates replica migration if proxy owner has died. diff --git a/Code/Framework/GridMate/GridMate/Session/Session.cpp b/Code/Framework/GridMate/GridMate/Session/Session.cpp index cf9edff496..9e8aab50ec 100644 --- a/Code/Framework/GridMate/GridMate/Session/Session.cpp +++ b/Code/Framework/GridMate/GridMate/Session/Session.cpp @@ -960,7 +960,7 @@ GridSession::AddMember(GridMember* member) replica->AttachReplicaChunk(member); } - m_replicaMgr->AddMaster(replica); + m_replicaMgr->AddPrimary(replica); member->m_isHost.Set(member->IsLocal()); } @@ -1583,7 +1583,7 @@ GridSession::OnStateCreate(HSM& sm, const HSM::Event& e) // Bind session replica Replica* stateReplica = Replica::CreateReplica("SessionStateInfo"); stateReplica->AttachReplicaChunk(m_state); - m_replicaMgr->AddMaster(stateReplica); + m_replicaMgr->AddPrimary(stateReplica); // Bind member replica bool isAdded = AddMember(m_myMember); @@ -2005,7 +2005,7 @@ GridMember::OnReplicaActivate(const ReplicaContext& rc) { // if this member is me... add my state to the system. AZ_Assert(m_session->GetMyMember() == this, "The only local member should be myMember too!"); - rc.m_rm->AddMaster(m_clientState->GetReplica()); + rc.m_rm->AddPrimary(m_clientState->GetReplica()); // Both member and client state are valid! send member joined message EBUS_DBG_EVENT(Debug::SessionDrillerBus, OnMemberJoined, m_session, this); @@ -2052,7 +2052,7 @@ GridMember::OnReplicaChangeOwnership(const ReplicaContext& rc) { (void)rc; AZ_Assert(m_session->IsMigratingHost(), "This function can be called only during host migration!"); - if (IsMaster()) + if (IsPrimary()) { // Host owns the members, if I became the owner means I am the HOST! if (m_session->m_myMember == this) @@ -2084,7 +2084,7 @@ GridMember::OnKick(AZ::u8 reason, const RpcContext& rc) m_session->Leave(false); } - return true; // this is called only on the master + return true; // this is called only on the primary } return false; } @@ -2320,8 +2320,8 @@ void GridMemberStateReplica::OnReplicaDeactivate(const ReplicaContext& rc) { (void)rc; - // for master (this is our state) we always keep it. So don't do anything. - if (IsMaster()) + // for primary (this is our state) we always keep it. So don't do anything. + if (IsPrimary()) { return; } diff --git a/Code/Framework/GridMate/Tests/Interest.cpp b/Code/Framework/GridMate/Tests/Interest.cpp index b4fb9b7654..c449c92083 100644 --- a/Code/Framework/GridMate/Tests/Interest.cpp +++ b/Code/Framework/GridMate/Tests/Interest.cpp @@ -534,7 +534,7 @@ namespace GridMate auto replica = Replica::CreateReplica("ProximityInterestHandlerRules"); m_rulesReplica = CreateAndAttachReplicaChunk(replica); - m_rm->AddMaster(replica); + m_rm->AddPrimary(replica); } void ProximityInterestHandler::OnRulesHandlerUnregistered(InterestManager* manager) @@ -658,7 +658,7 @@ class Integ_InterestTest { AZ_Printf("GridMate", "InterestTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); @@ -674,7 +674,7 @@ class Integ_InterestTest { AZ_Printf("GridMate", "InterestTestChunk::OnReplicaDeactivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); @@ -734,7 +734,7 @@ class Integ_InterestTest m_replica->m_data.Set(m_num); m_replica->m_bitmaskAttributeData.Set(1 << i); - m_session->GetReplicaMgr()->AddMaster(r); + m_session->GetReplicaMgr()->AddPrimary(r); } void UpdateAttribute() @@ -952,7 +952,7 @@ public: if (numUpdates == 250) { - // Checking everybody lost all replicas (except master) + // Checking everybody lost all replicas (except primary) for (int i = 0; i < k_numMachines; ++i) { for (int j = 0; j < k_numMachines; ++j) @@ -1079,11 +1079,11 @@ class LargeWorldTest void OnReplicaActivate(const ReplicaContext& rc) override { - /*if (!IsMaster())*/ + /*if (!IsPrimary())*/ /*{ AZ_Printf("GridMate", "LargeWorldTestChunk::OnReplicaActivate repId=%08X(%s) fromPeerId=%08X localPeerId=%08X\n", GetReplicaId(), - IsMaster() ? "master" : "proxy", + IsPrimary() ? "primary" : "proxy", rc.m_peer ? rc.m_peer->GetId() : 0, rc.m_rm->GetLocalPeerId()); }*/ @@ -1214,7 +1214,7 @@ class LargeWorldTest m_replicas.push_back(replica); - m_session->GetReplicaMgr()->AddMaster(r); + m_session->GetReplicaMgr()->AddPrimary(r); } void PopulateWorld() @@ -1453,7 +1453,7 @@ public: if (numUpdates == 250) { - // Checking everybody lost all replicas (except master) + // Checking everybody lost all replicas (except primary) for (int i = 0; i < k_numMachines; ++i) { /*for (int j = 0; j < k_numMachines; ++j) diff --git a/Code/Framework/GridMate/Tests/Replica.cpp b/Code/Framework/GridMate/Tests/Replica.cpp index 4d2f8d1e3a..624ee8c7e0 100644 --- a/Code/Framework/GridMate/Tests/Replica.cpp +++ b/Code/Framework/GridMate/Tests/Replica.cpp @@ -1615,7 +1615,7 @@ public: { (void)f; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, GetReplica()->IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, GetReplica()->IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } @@ -1653,14 +1653,14 @@ public: (void)rc; if (rc.m_rm->GetUserContext(12345)) { - AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", GetReplica()->IsMaster() ? "master" : "proxy", rc.m_rm->GetUserContext(12345)); + AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", GetReplica()->IsPrimary() ? "primary" : "proxy", rc.m_rm->GetUserContext(12345)); } if (IsProxy()) { Bind(aznew MyObj()); } - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(MigratableReplicaDebugMsgs::EBus, OnNewOwner, GetReplicaId(), rc.m_rm); } @@ -1679,9 +1679,9 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { (void)rc; - AZ_TracePrintf("GridMate", "Migratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsMaster() ? "master" : "proxy", (int) rc.m_rm->GetLocalPeerId()); + AZ_TracePrintf("GridMate", "Migratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsPrimary() ? "primary" : "proxy", (int) rc.m_rm->GetLocalPeerId()); - if (IsMaster()) + if (IsPrimary()) { EBUS_EVENT(MigratableReplicaDebugMsgs::EBus, OnNewOwner, GetReplicaId(), rc.m_rm); } @@ -1725,7 +1725,7 @@ protected: { (void)f; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler123 requested at %u with %g on %s at %u.\n", rc.m_timestamp, f, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler2(const float& f, int p2, const RpcContext& rc) @@ -1733,7 +1733,7 @@ protected: (void)f; (void)p2; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler2 requested at %u with %g,%d on %s at %u.\n", rc.m_timestamp, f, p2, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler2 requested at %u with %g,%d on %s at %u.\n", rc.m_timestamp, f, p2, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler3(const float& f, int p2, EBla p3, const RpcContext& rc) @@ -1742,7 +1742,7 @@ protected: (void)p2; (void)p3; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler3 requested at %u with %g,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler3 requested at %u with %g,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandler4(const float& f, int p2, EBla p3, const IntVectorType& p4, const RpcContext& rc) @@ -1752,13 +1752,13 @@ protected: (void)p3; (void)p4; (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandler4 requested at %u with %g,%d,%d,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, p4[0], p4[1], IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandler4 requested at %u with %g,%d,%d,%d,%d on %s at %u.\n", rc.m_timestamp, f, p2, p3, p4[0], p4[1], IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); return true; } bool MyHandlerUnreliable(const int& i, const RpcContext& rc) { (void)rc; - AZ_TracePrintf("GridMate", "Executed MyHandlerUnreliable requested at %u with %d on %s at %u.\n", rc.m_timestamp, i, IsMaster() ? "Master" : "Proxy", rc.m_realTime); + AZ_TracePrintf("GridMate", "Executed MyHandlerUnreliable requested at %u with %d on %s at %u.\n", rc.m_timestamp, i, IsPrimary() ? "Primary" : "Proxy", rc.m_realTime); AZ_TEST_ASSERT(i > m_prevUnreliableValue); if ((i - m_prevUnreliableValue) > 1) { @@ -1824,7 +1824,7 @@ public: (void)rc; if (rc.m_rm->GetUserContext(12345)) { - AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", IsMaster() ? "master" : "proxy", rc.m_rm->GetUserContext(12345)); + AZ_TracePrintf("GridMate", "Activate %s with UserData:%p\n", IsPrimary() ? "primary" : "proxy", rc.m_rm->GetUserContext(12345)); } if (IsProxy()) { @@ -1845,7 +1845,7 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { (void)rc; - AZ_TracePrintf("GridMate", "NonMigratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsMaster() ? "master" : "proxy", (int) rc.m_rm->GetLocalPeerId()); + AZ_TracePrintf("GridMate", "NonMigratable replica 0x%x became %s on Peer %d\n", (int) GetReplicaId(), IsPrimary() ? "primary" : "proxy", (int) rc.m_rm->GetLocalPeerId()); } void Bind(MyObj* pObj) @@ -1950,7 +1950,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) // put something on s1 to get it going auto rep = Replica::CreateReplica(nullptr); s1rep1 = CreateAndAttachReplicaChunk(rep); - s1rep1id = sessions[s1].GetReplicaMgr().AddMaster(rep); + s1rep1id = sessions[s1].GetReplicaMgr().AddPrimary(rep); s1rep1->Bind(s1obj1 = aznew MyObj()); // connect s2 to s1 @@ -1993,7 +1993,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s2rep1 = CreateAndAttachReplicaChunk(newReplica); - s2rep1id = sessions[s2].GetReplicaMgr().AddMaster(newReplica); + s2rep1id = sessions[s2].GetReplicaMgr().AddPrimary(newReplica); s2rep1->Bind(s2obj1 = aznew MyObj()); } else @@ -2020,7 +2020,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s1rep2 = CreateAndAttachReplicaChunk(newReplica); - s1rep2id = sessions[s1].GetReplicaMgr().AddMaster(newReplica); + s1rep2id = sessions[s1].GetReplicaMgr().AddPrimary(newReplica); s1rep2->Bind(s1obj2 = aznew MyObj); } else @@ -2041,7 +2041,7 @@ TEST_F(Integ_ReplicaGMTest, ReplicaTest) { auto newReplica = Replica::CreateReplica(nullptr); s3rep1 = CreateAndAttachReplicaChunk(newReplica); - s3rep1id = sessions[s3].GetReplicaMgr().AddMaster(newReplica); + s3rep1id = sessions[s3].GetReplicaMgr().AddPrimary(newReplica); s3rep1->Bind(s3obj1 = aznew MyObj()); } else @@ -2289,13 +2289,13 @@ TEST_F(Integ_ForcedReplicaMigrationTest, ForcedReplicaMigrationTest) { auto rep = Replica::CreateReplica(nullptr); migrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); AZ_TEST_ASSERT(m_replicaOwnership[migrRep[i]->GetReplicaId()] == &peers[i].GetReplicaMgr()); } { auto rep = Replica::CreateReplica(nullptr); nonMigrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } } addReplicas = false; @@ -2418,7 +2418,7 @@ public: void OnReplicaActivate(const ReplicaContext& rc) override { - if (IsMaster()) + if (IsPrimary()) { m_owner.Set(rc.m_rm->GetLocalPeerId() - 1); m_control.Set(rc.m_rm->GetLocalPeerId() - 1); @@ -2427,9 +2427,9 @@ public: void OnReplicaChangeOwnership(const ReplicaContext& rc) override { - if (IsMaster()) + if (IsPrimary()) { - AZ_TracePrintf("GridMate", "OnChangeOwnership: 0x%04x Became master on node %d\n", GetReplicaId(), rc.m_rm->GetLocalPeerId() - 1); + AZ_TracePrintf("GridMate", "OnChangeOwnership: 0x%04x Became primary on node %d\n", GetReplicaId(), rc.m_rm->GetLocalPeerId() - 1); m_owner.Set(rc.m_rm->GetLocalPeerId() - 1); } else @@ -2591,18 +2591,18 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_always = CreateAndAttachReplicaChunk(rep); - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_never = CreateAndAttachReplicaChunk(rep); - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nodes[iNode].m_sometimes = CreateAndAttachReplicaChunk(rep); nodes[iNode].m_sometimes->m_acceptMigrationRequests = iNode == Peer1 || iNode == Client1; - nodes[iNode].m_session.GetReplicaMgr().AddMaster(rep); + nodes[iNode].m_session.GetReplicaMgr().AddPrimary(rep); } } } @@ -2675,7 +2675,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client1].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client1].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client1].m_always->m_owner.Get() == Client2); - AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsPrimary()); // C1 -> C2 -> Host (2nd migration) ReplicaPtr aHonC1 = nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId()); @@ -2737,7 +2737,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Peer1].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Peer1].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_always->m_owner.Get() == Peer2); - AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_always->m_control.Get() == Peer2); // P2 -> Host -> C2 (both at same time, with C2 arriving second) @@ -2750,7 +2750,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(aP2onH->m_accepted == 1); AZ_TEST_ASSERT(aP2onH->GetReplica()->IsProxy()); AZ_TEST_ASSERT(aP2onH->m_owner.Get() == Client2); - AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer2].m_always->m_control.Get() == Client2); // Host -> C1 @@ -2758,7 +2758,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Host].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Host].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Host].m_always->m_owner.Get() == Client1); - AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Host].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Host].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Host].m_always->m_control.Get() == Client1); // C1 -> C2 -> Host (2nd migration) @@ -2771,7 +2771,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(aC1onC2->m_accepted == 1); AZ_TEST_ASSERT(aC1onC2->GetReplica()->IsProxy()); AZ_TEST_ASSERT(aC1onC2->m_owner.Get() == Host); - AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client1].m_always->m_control.Get() == Host); // C2 -> P1 @@ -2779,13 +2779,13 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client2].m_always->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client2].m_always->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_always->m_owner.Get() == Peer1); - AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_always->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_always->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_always->m_control.Get() == Peer1); // P1 -> C1 (Forbidden) AZ_TEST_ASSERT(nodes[Peer1].m_never->m_requests == 0); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Peer1].m_never->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_never->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_owner.Get() == Peer1); AZ_TEST_ASSERT(nodes[Client1].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_never->m_control.Get() == Peer1); @@ -2793,7 +2793,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) // C2 -> P2 (Forbidden) AZ_TEST_ASSERT(nodes[Client2].m_never->m_requests == 0); AZ_TEST_ASSERT(nodes[Client2].m_never->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Client2].m_never->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_never->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_never->m_owner.Get() == Client2); AZ_TEST_ASSERT(nodes[Peer2].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_never->m_control.Get() == Client2); @@ -2803,7 +2803,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_accepted == 1); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_owner.Get() == Host); - AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_sometimes->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Peer1].m_sometimes->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer1].m_sometimes->m_control.Get() == Host); // C1 -> P1 @@ -2811,13 +2811,13 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_accepted == 1); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->GetReplica()->IsProxy()); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_owner.Get() == Peer1); - AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_sometimes->GetReplicaId())->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer1].m_session.GetReplicaMgr().FindReplica(nodes[Client1].m_sometimes->GetReplicaId())->IsPrimary()); AZ_TEST_ASSERT(nodes[Client1].m_sometimes->m_control.Get() == Peer1); // P2 -> C2 (Forbidden) AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_requests == 1); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_owner.Get() == Peer2); AZ_TEST_ASSERT(nodes[Client2].m_session.GetReplicaMgr().FindReplica(nodes[Peer2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Peer2].m_sometimes->m_control.Get() == Peer2); @@ -2825,7 +2825,7 @@ TEST_F(Integ_ReplicaMigrationRequestTest, ReplicaMigrationRequestTest) // C2 -> Host (Forbidden) AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_requests == 1); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_accepted == 0); - AZ_TEST_ASSERT(nodes[Client2].m_sometimes->GetReplica()->IsMaster()); + AZ_TEST_ASSERT(nodes[Client2].m_sometimes->GetReplica()->IsPrimary()); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_owner.Get() == Client2); AZ_TEST_ASSERT(nodes[Host].m_session.GetReplicaMgr().FindReplica(nodes[Client2].m_never->GetReplicaId())->IsProxy()); AZ_TEST_ASSERT(nodes[Client2].m_sometimes->m_control.Get() == Client2); @@ -2946,12 +2946,12 @@ TEST_F(Integ_PeerRejoinTest, PeerRejoinTest) { auto rep = Replica::CreateReplica(nullptr); migrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } { auto rep = Replica::CreateReplica(nullptr); nonMigrRep[i] = CreateAndAttachReplicaChunk(rep, aznew MyObj()); - peers[i].GetReplicaMgr().AddMaster(rep); + peers[i].GetReplicaMgr().AddPrimary(rep); } } addReplicas = false; @@ -3099,7 +3099,7 @@ public: { // make sure the requestor is set to s1 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s1 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS1.Modify([](int& value) { ++value; return true; }); } @@ -3114,7 +3114,7 @@ public: { // make sure the requestor is set to s2 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s2 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS2.Modify([](int& value) { ++value; return true; }); } @@ -3129,7 +3129,7 @@ public: { // make sure the requestor is set to s3 AZ_TEST_ASSERT(rpcContext.m_sourcePeer == s3 + 1); - if (IsMaster()) + if (IsPrimary()) { m_nAuthoritativeOnlyRpcCallsFromS3.Modify([](int& value) { ++value; return true; }); } @@ -3168,7 +3168,7 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) ReplicaChunkDescriptorTable::Get().RegisterChunkType(); MPSession sessions[nSessions]; - ReplicaPtr masters[nSessions]; + ReplicaPtr primarys[nSessions]; // initialize transport int basePort = 4427; @@ -3202,10 +3202,10 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) for (int i = 0; i < nSessions; ++i) { AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().IsReady()); - masters[i] = Replica::CreateReplica("ReplicationSecurityOptionsTest::TestReplica"); + primarys[i] = Replica::CreateReplica("ReplicationSecurityOptionsTest::TestReplica"); TestChunkPtr chunk = CreateReplicaChunk(); - masters[i]->AttachReplicaChunk(chunk); - sessions[i].GetReplicaMgr().AddMaster(masters[i]); + primarys[i]->AttachReplicaChunk(chunk); + sessions[i].GetReplicaMgr().AddPrimary(primarys[i]); } } @@ -3214,9 +3214,9 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_START_TRACE_SUPPRESSION; for (int i = 0; i < nSessions; ++i) { - sessions[s1].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS1(); - sessions[s2].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS2(); - sessions[s3].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS3(); + sessions[s1].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS1(); + sessions[s2].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS2(); + sessions[s3].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->ForwardSourcePeerRpcFromS3(); } } @@ -3227,36 +3227,36 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_STOP_TRACE_SUPPRESSION(2); // All chunks should have received the call from the host - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1 == 1); // the host chunk should have received calls from both clients - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); // the chunk on s2 should receive its own call but not from s3 - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 0); // the chunk on s3 should receive its own call but not from s2 - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3 == 1); // all datasets should have propagated properly for (int i = 0; i < nSessions; ++i) { - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s1]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s2]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == masters[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get() == primarys[s3]->FindReplicaChunk()->m_nForwardSourcePeerRpcCallsFromS3.Get()); } } @@ -3265,9 +3265,9 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_START_TRACE_SUPPRESSION; for (int i = 0; i < nSessions; ++i) { - sessions[s1].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS1(); - sessions[s2].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS2(); - sessions[s3].GetReplicaMgr().FindReplica(masters[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS3(); + sessions[s1].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS1(); + sessions[s2].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS2(); + sessions[s3].GetReplicaMgr().FindReplica(primarys[i]->GetRepId())->FindReplicaChunk()->AuthoritativeOnlyRpcFromS3(); } } @@ -3278,40 +3278,40 @@ TEST_F(Integ_ReplicationSecurityOptionsTest, ReplicationSecurityOptionsTest) AZ_TEST_STOP_TRACE_SUPPRESSION(6); // Each chunk should have received their own AuthoritativeOnlyRpc once. - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 1); // Calls from other nodes should have been discarded. - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); - AZ_TEST_ASSERT(masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); - AZ_TEST_ASSERT(masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); - AZ_TEST_ASSERT(masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); + AZ_TEST_ASSERT(primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); + AZ_TEST_ASSERT(primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1 == 0); + AZ_TEST_ASSERT(primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2 == 0); // Calls should have successfully propagated to the other 2 proxies - AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); - AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); - AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); - AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); - AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); + AZ_TEST_ASSERT(sessions[s1].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(sessions[s2].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS3 == 1); + AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS1 == 1); + AZ_TEST_ASSERT(sessions[s3].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyProxyRpcCallsFromS2 == 1); // all datasets should have propagated properly for (int i = 0; i < nSessions; ++i) { - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s1]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s1]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s2]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s2]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); - AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(masters[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == masters[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS1.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS2.Get()); + AZ_TEST_ASSERT(sessions[i].GetReplicaMgr().FindReplica(primarys[s3]->GetRepId())->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get() == primarys[s3]->FindReplicaChunk()->m_nAuthoritativeOnlyRpcCallsFromS3.Get()); } } @@ -3594,7 +3594,7 @@ public: auto rep = Replica::CreateReplica(nullptr); auto chunk = CreateAndAttachReplicaChunk(rep); replicas.push_back(AZStd::make_pair(rep, chunk)); - session.GetReplicaMgr().AddMaster(rep); + session.GetReplicaMgr().AddPrimary(rep); } } @@ -3730,7 +3730,7 @@ public: { auto rep = Replica::CreateReplica(nullptr); chunks[i] = CreateAndAttachReplicaChunk(rep); - sessions[sHost].GetReplicaMgr().AddMaster(rep); + sessions[sHost].GetReplicaMgr().AddPrimary(rep); } // connect to host diff --git a/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp b/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp index 3f9db2ba0e..c3dac305db 100644 --- a/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaBehavior.cpp @@ -687,7 +687,7 @@ namespace ReplicaBehavior { AZ_TEST_ASSERT(chunk->Data1.IsDefaultValue()); AZ_TEST_ASSERT(chunk->Data2.IsDefaultValue()); - m_replicaIdDefault = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaIdDefault = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -725,7 +725,7 @@ namespace ReplicaBehavior { AZ_TEST_ASSERT(!chunk->Data1.IsDefaultValue()); AZ_TEST_ASSERT(!chunk->Data2.IsDefaultValue()); - m_replicaIdModified = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaIdModified = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } break; } @@ -816,7 +816,7 @@ namespace ReplicaBehavior { LargeChunkWithDefaults* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_ReplicaDefaultDataSetDriller() @@ -923,13 +923,13 @@ namespace ReplicaBehavior { ChunkWithBools* chunk1 = CreateAndAttachReplicaChunk(replica1); AZ_TEST_ASSERT(chunk1); - m_replicaBoolsId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica1); + m_replicaBoolsId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica1); ReplicaPtr replica2 = Replica::CreateReplica(nullptr); ChunkWithShortInts* chunk2 = CreateAndAttachReplicaChunk(replica2); AZ_TEST_ASSERT(chunk2); - m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddMaster(replica2); + m_replicaU8Id = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica2); } ~Integ_Replica_ComparePackingBoolsVsU8() @@ -1058,7 +1058,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessary() @@ -1155,7 +1155,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckDataSetStreamIsntWrittenMoreThanNecessaryOnceDirty() @@ -1249,7 +1249,7 @@ namespace ReplicaBehavior { ForcingDirtyTestChunk* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckReplicaIsntSentWithNoChanges() @@ -1360,7 +1360,7 @@ namespace ReplicaBehavior { auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_CheckEntityScriptReplicaIsntSentWithNoChanges() diff --git a/Code/Framework/GridMate/Tests/ReplicaMedium.cpp b/Code/Framework/GridMate/Tests/ReplicaMedium.cpp index 7c04c26487..fbdf4ee493 100644 --- a/Code/Framework/GridMate/Tests/ReplicaMedium.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaMedium.cpp @@ -73,12 +73,12 @@ public: static const char* GetChunkName() { return "RPCChunk"; } RPCChunk() - : m_fromMasterBroadcast(0) - , m_fromMasterNotBroadcast(0) + : m_fromPrimaryBroadcast(0) + , m_fromPrimaryNotBroadcast(0) , m_fromProxyBroadcast(0) , m_fromProxyNotBroadcast(0) - , FromMasterBroadcast("FromMasterBroadcast") - , FromMasterNotBroadcast("FromMasterNotBroadcast") + , FromPrimaryBroadcast("FromPrimaryBroadcast") + , FromPrimaryNotBroadcast("FromPrimaryNotBroadcast") , FromProxyBroadcast("FromProxyBroadcast") , FromProxyNotBroadcast("FromProxyNotBroadcast") , BroadcastInt("BroadcastInt") @@ -86,30 +86,30 @@ public: bool IsReplicaMigratable() override { return false; } - bool FromMasterBroadcastFn(const RpcContext&) + bool FromPrimaryBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromMasterBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - m_fromMasterBroadcast++; + AZ_TracePrintf("GridMate", "Executed FromPrimaryBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + m_fromPrimaryBroadcast++; return true; } - bool FromMasterNotBroadcastFn(const RpcContext&) + bool FromPrimaryNotBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromMasterNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - m_fromMasterNotBroadcast++; + AZ_TracePrintf("GridMate", "Executed FromPrimaryNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + m_fromPrimaryNotBroadcast++; return false; } bool FromProxyBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromProxyBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed FromProxyBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); m_fromProxyBroadcast++; return true; } bool FromProxyNotBroadcastFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed FromProxyNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed FromProxyNotBroadcast %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); m_fromProxyNotBroadcast++; return false; } @@ -120,14 +120,14 @@ public: return true; } - int m_fromMasterBroadcast; - int m_fromMasterNotBroadcast; + int m_fromPrimaryBroadcast; + int m_fromPrimaryNotBroadcast; int m_fromProxyBroadcast; int m_fromProxyNotBroadcast; AZStd::vector m_sentData; - Rpc<>::BindInterface FromMasterBroadcast; - Rpc<>::BindInterface FromMasterNotBroadcast; + Rpc<>::BindInterface FromPrimaryBroadcast; + Rpc<>::BindInterface FromPrimaryNotBroadcast; Rpc<>::BindInterface FromProxyBroadcast; Rpc<>::BindInterface FromProxyNotBroadcast; Rpc >::BindInterface BroadcastInt; @@ -158,21 +158,21 @@ public: bool Zero(const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[0]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[0]; (void) list; return true; } bool One(AZ::u32 t1, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[1]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[1]; list.push_back(t1); return true; } bool Two(AZ::u32 t1, AZ::u32 t2, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[2]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[2]; list.push_back(t1); list.push_back(t2); return true; @@ -180,7 +180,7 @@ public: bool Three(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[3]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[3]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -189,7 +189,7 @@ public: bool Four(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[4]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[4]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -199,7 +199,7 @@ public: bool Five(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[5]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[5]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -210,7 +210,7 @@ public: bool Six(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[6]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[6]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -222,7 +222,7 @@ public: bool Seven(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[7]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[7]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -235,7 +235,7 @@ public: bool Eight(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, AZ::u32 t8, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[8]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[8]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -249,7 +249,7 @@ public: bool Nine(AZ::u32 t1, AZ::u32 t2, AZ::u32 t3, AZ::u32 t4, AZ::u32 t5, AZ::u32 t6, AZ::u32 t7, AZ::u32 t8, AZ::u32 t9, const RpcContext&) { - auto& list = (IsMaster() ? m_sentData : m_receivedData)[9]; + auto& list = (IsPrimary() ? m_sentData : m_receivedData)[9]; list.push_back(t1); list.push_back(t2); list.push_back(t3); @@ -890,7 +890,7 @@ public: // put something on s1 to get it going auto replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } RPCChunk::Ptr m_chunk; @@ -905,11 +905,11 @@ TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec) switch (tick) { case 10: - m_chunk->FromMasterBroadcast(); + m_chunk->FromPrimaryBroadcast(); break; case 20: - m_chunk->FromMasterNotBroadcast(); + m_chunk->FromPrimaryNotBroadcast(); break; case 30: @@ -932,13 +932,13 @@ TEST_F(Integ_ReplicaChunkRPCExec, ReplicaChunkRPCExec) auto s2proxy = m_sessions[s2].GetReplicaMgr().FindReplica(m_replicaId)->FindReplicaChunk(); auto s3proxy = m_sessions[s3].GetReplicaMgr().FindReplica(m_replicaId)->FindReplicaChunk(); - AZ_TEST_ASSERT(s1host->m_fromMasterBroadcast == 1); - AZ_TEST_ASSERT(s2proxy->m_fromMasterBroadcast == 1); - AZ_TEST_ASSERT(s3proxy->m_fromMasterBroadcast == 1); + AZ_TEST_ASSERT(s1host->m_fromPrimaryBroadcast == 1); + AZ_TEST_ASSERT(s2proxy->m_fromPrimaryBroadcast == 1); + AZ_TEST_ASSERT(s3proxy->m_fromPrimaryBroadcast == 1); - AZ_TEST_ASSERT(s1host->m_fromMasterNotBroadcast == 1); - AZ_TEST_ASSERT(s2proxy->m_fromMasterNotBroadcast == 0); - AZ_TEST_ASSERT(s3proxy->m_fromMasterNotBroadcast == 0); + AZ_TEST_ASSERT(s1host->m_fromPrimaryNotBroadcast == 1); + AZ_TEST_ASSERT(s2proxy->m_fromPrimaryNotBroadcast == 0); + AZ_TEST_ASSERT(s3proxy->m_fromPrimaryNotBroadcast == 0); AZ_TEST_ASSERT(s1host->m_fromProxyBroadcast == 1); AZ_TEST_ASSERT(s2proxy->m_fromProxyBroadcast == 1); @@ -965,12 +965,12 @@ public: GM_CLASS_ALLOCATOR(DestroyRPCChunk); DestroyRPCChunk() - : DestroyFromMaster("DestroyFromMaster") + : DestroyFromPrimary("DestroyFromPrimary") , DestroyFromProxy("DestroyFromProxy") , BeforeDestroyFromProxy("BeforeDestroyFromProxy") , AfterDestroyFromProxy("AfterDestroyFromProxy") - , BeforeDestroyFromMaster("BeforeDestroyFromMaster") - , AfterDestroyFromMaster("AfterDestroyFromMaster") + , BeforeDestroyFromPrimary("BeforeDestroyFromPrimary") + , AfterDestroyFromPrimary("AfterDestroyFromPrimary") { } @@ -979,11 +979,11 @@ public: bool IsReplicaMigratable() override { return false; } - bool DestroyFromMasterFn(const RpcContext&) + bool DestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed DestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_destroyFromMasterCalls; - if (GetReplica()->IsMaster()) + AZ_TracePrintf("GridMate", "Executed DestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_destroyFromPrimaryCalls; + if (GetReplica()->IsPrimary()) { GetReplica()->Destroy(); } @@ -992,9 +992,9 @@ public: bool DestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed DestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed DestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_destroyFromProxyCalls; - if (GetReplica()->IsMaster()) + if (GetReplica()->IsPrimary()) { GetReplica()->Destroy(); } @@ -1003,53 +1003,53 @@ public: bool BeforeDestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_beforeDestroyFromProxyCalls; return true; } bool AfterDestroyFromProxyFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed AfterDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); + AZ_TracePrintf("GridMate", "Executed AfterDestroyFromProxy %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); ++s_afterDestroyFromProxyCalls; return true; } - bool BeforeDestroyFromMasterFn(const RpcContext&) + bool BeforeDestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_beforeDestroyFromMasterCalls; + AZ_TracePrintf("GridMate", "Executed BeforeDestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_beforeDestroyFromPrimaryCalls; return true; } - bool AfterDestroyFromMasterFn(const RpcContext&) + bool AfterDestroyFromPrimaryFn(const RpcContext&) { - AZ_TracePrintf("GridMate", "Executed AfterDestroyFromMaster %d %s\n", GetReplicaId(), GetReplica()->IsMaster() ? "master" : "proxy"); - ++s_afterDestroyFromMasterCalls; + AZ_TracePrintf("GridMate", "Executed AfterDestroyFromPrimary %d %s\n", GetReplicaId(), GetReplica()->IsPrimary() ? "primary" : "proxy"); + ++s_afterDestroyFromPrimaryCalls; return true; } - Rpc<>::BindInterface DestroyFromMaster; + Rpc<>::BindInterface DestroyFromPrimary; Rpc<>::BindInterface DestroyFromProxy; Rpc<>::BindInterface BeforeDestroyFromProxy; Rpc<>::BindInterface AfterDestroyFromProxy; - Rpc<>::BindInterface BeforeDestroyFromMaster; - Rpc<>::BindInterface AfterDestroyFromMaster; + Rpc<>::BindInterface BeforeDestroyFromPrimary; + Rpc<>::BindInterface AfterDestroyFromPrimary; - static int s_destroyFromMasterCalls; - static int s_beforeDestroyFromMasterCalls; - static int s_afterDestroyFromMasterCalls; + static int s_destroyFromPrimaryCalls; + static int s_beforeDestroyFromPrimaryCalls; + static int s_afterDestroyFromPrimaryCalls; static int s_destroyFromProxyCalls; static int s_beforeDestroyFromProxyCalls; static int s_afterDestroyFromProxyCalls; }; int DestroyRPCChunk::s_destroyFromProxyCalls = 0; -int DestroyRPCChunk::s_destroyFromMasterCalls = 0; +int DestroyRPCChunk::s_destroyFromPrimaryCalls = 0; int DestroyRPCChunk::s_beforeDestroyFromProxyCalls = 0; int DestroyRPCChunk::s_afterDestroyFromProxyCalls = 0; -int DestroyRPCChunk::s_beforeDestroyFromMasterCalls = 0; -int DestroyRPCChunk::s_afterDestroyFromMasterCalls = 0; +int DestroyRPCChunk::s_beforeDestroyFromPrimaryCalls = 0; +int DestroyRPCChunk::s_afterDestroyFromPrimaryCalls = 0; //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- @@ -1077,7 +1077,7 @@ public: { auto replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_repId[i] = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_repId[i] = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -1092,12 +1092,12 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC) { case 10: { - // calling destroy on master - auto master = m_sessions[sHost].GetReplicaMgr().FindReplica(m_repId[0]); - auto masterChunk = master->FindReplicaChunk(); - masterChunk->BeforeDestroyFromMaster(); - masterChunk->DestroyFromMaster(); - masterChunk->AfterDestroyFromMaster(); + // calling destroy on primary + auto primary = m_sessions[sHost].GetReplicaMgr().FindReplica(m_repId[0]); + auto primaryChunk = primary->FindReplicaChunk(); + primaryChunk->BeforeDestroyFromPrimary(); + primaryChunk->DestroyFromPrimary(); + primaryChunk->AfterDestroyFromPrimary(); // calling destroy on proxy auto proxy = m_sessions[s2].GetReplicaMgr().FindReplica(m_repId[1]); @@ -1113,15 +1113,15 @@ TEST_F(Integ_ReplicaDestroyedInRPC, ReplicaDestroyedInRPC) { // checking if before destroy RPC was called on every peer AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromProxyCalls == nSessions); - AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromMasterCalls == nSessions); + AZ_TEST_ASSERT(DestroyRPCChunk::s_beforeDestroyFromPrimaryCalls == nSessions); // checking if destroy itself was called on every peer AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromProxyCalls == nSessions); - AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromMasterCalls == nSessions); + AZ_TEST_ASSERT(DestroyRPCChunk::s_destroyFromPrimaryCalls == nSessions); // checking if after destroy RPC was never called AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromProxyCalls == 0); // RPCs that arrive via the network after deactivation should be dropped. - AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromMasterCalls == 1); // RPCs explicitly called on an inactive replica should still be executed. + AZ_TEST_ASSERT(DestroyRPCChunk::s_afterDestroyFromPrimaryCalls == 1); // RPCs explicitly called on an inactive replica should still be executed. return TestStatus::Completed; } @@ -1157,7 +1157,7 @@ public: { // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1232,7 +1232,7 @@ public: // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1286,7 +1286,7 @@ public: // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -1391,7 +1391,7 @@ public: { // put something on s1 to get it going m_replica = Replica::CreateReplica(nullptr); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } @@ -1453,7 +1453,7 @@ public: { ReplicaPtr replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); AZ_TEST_ASSERT(m_chunk->m_attaches == 1); AZ_TEST_ASSERT(m_chunk->m_activates == 1); @@ -1531,7 +1531,7 @@ public: auto chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); } - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); auto numChunks = replica->GetNumChunks(); AZ_TEST_ASSERT(numChunks == GM_MAX_CHUNKS_PER_REPLICA); @@ -1594,7 +1594,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); AZ_TEST_ASSERT(m_chunk->m_attaches == 1); AZ_TEST_ASSERT(m_chunk->m_activates == 1); @@ -1820,16 +1820,16 @@ public: ++m_numRequestChangeOwnership; } - void OnReplicaChangeOwnership(Replica* replica, bool wasMaster) override + void OnReplicaChangeOwnership(Replica* replica, bool wasPrimary) override { AZ_TEST_ASSERT(replica); switch (m_numChangedOwnership) { case 0: // host loses ownership - AZ_TEST_ASSERT(replica->IsProxy() && wasMaster == true); + AZ_TEST_ASSERT(replica->IsProxy() && wasPrimary == true); break; case 1: // peer acquires ownership - AZ_TEST_ASSERT(replica->IsMaster() && wasMaster == false); + AZ_TEST_ASSERT(replica->IsPrimary() && wasPrimary == false); break; default: AZ_TEST_ASSERT(0); @@ -2008,7 +2008,7 @@ public: ReplicaPtr replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~Integ_ReplicaDriller() @@ -2038,7 +2038,7 @@ TEST_F(Integ_ReplicaDriller, ReplicaDriller) { auto rep = m_sessions[s2].GetReplicaMgr().FindReplica(m_replicaId); AZ_TEST_ASSERT(rep); - AZ_TEST_ASSERT(rep->IsMaster()); + AZ_TEST_ASSERT(rep->IsPrimary()); rep->Destroy(); break; } @@ -2110,7 +2110,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } @@ -2172,16 +2172,16 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); - m_masterHandler.reset(aznew CustomHandler()); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); + m_primaryHandler.reset(aznew CustomHandler()); m_proxyHandler.reset(aznew CustomHandler()); - m_chunk->SetHandler(m_masterHandler.get()); + m_chunk->SetHandler(m_primaryHandler.get()); } ReplicaPtr m_replica; ReplicaId m_replicaId; CustomHandlerChunk::Ptr m_chunk; - AZStd::scoped_ptr m_masterHandler; + AZStd::scoped_ptr m_primaryHandler; AZStd::scoped_ptr m_proxyHandler; }; @@ -2262,7 +2262,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -2338,7 +2338,7 @@ public: { m_replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(m_replica); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(m_replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(m_replica); } ReplicaPtr m_replica; @@ -2488,7 +2488,7 @@ public: m_chunks[i] = CreateAndAttachReplicaChunk(replica); m_chunks[i]->m_value.Set(i + 1); // setting dataset values to 1..kNumReplicas m_chunks[i]->SetPriority(k_replicaPriorityNormal + static_cast(i)); // the later created - the higher priorities, so should be sent in reverse order - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } } @@ -2594,7 +2594,7 @@ public: ReplicaPtr replica = Replica::CreateReplica(nullptr); m_chunk = CreateAndAttachReplicaChunk(replica); - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } SuspendUpdatesChunk::Ptr m_chunk = nullptr; @@ -2684,9 +2684,9 @@ public: void OnReplicaActivate(const GridMate::ReplicaContext&) override { - if (IsMaster()) + if (IsPrimary()) { - nMasterActivations++; + nPrimaryActivations++; } else { @@ -2694,11 +2694,11 @@ public: } } - static int nMasterActivations; + static int nPrimaryActivations; static int nProxyActivations; }; }; -int Integ_BasicHostChunkDescriptorTest::HostChunk::nMasterActivations = 0; +int Integ_BasicHostChunkDescriptorTest::HostChunk::nPrimaryActivations = 0; int Integ_BasicHostChunkDescriptorTest::HostChunk::nProxyActivations = 0; TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) @@ -2744,25 +2744,25 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) { hostReplica = Replica::CreateReplica("HostReplica"); hostReplica->AttachReplicaChunk(CreateReplicaChunk()); - nodes[Host].GetReplicaMgr().AddMaster(hostReplica); + nodes[Host].GetReplicaMgr().AddPrimary(hostReplica); } if (tick == 300) { - AZ_TEST_ASSERT(HostChunk::nMasterActivations == 1); + AZ_TEST_ASSERT(HostChunk::nPrimaryActivations == 1); AZ_TEST_ASSERT(HostChunk::nProxyActivations == 1); AZ_TEST_ASSERT(nodes[Client].GetReplicaMgr().FindReplica(hostReplica->GetRepId())->FindReplicaChunk()); AZ_TEST_START_TRACE_SUPPRESSION; clientReplica = Replica::CreateReplica("ClientReplica"); clientReplica->AttachReplicaChunk(CreateReplicaChunk()); - nodes[Client].GetReplicaMgr().AddMaster(clientReplica); + nodes[Client].GetReplicaMgr().AddPrimary(clientReplica); } if (tick == 400) { AZ_TEST_STOP_TRACE_SUPPRESSION(1); - AZ_TEST_ASSERT(HostChunk::nMasterActivations == 2); + AZ_TEST_ASSERT(HostChunk::nPrimaryActivations == 2); AZ_TEST_ASSERT(HostChunk::nProxyActivations == 1); AZ_TEST_ASSERT(!nodes[Host].GetReplicaMgr().FindReplica(clientReplica->GetRepId())->FindReplicaChunk()); } @@ -2792,10 +2792,10 @@ TEST_F(Integ_BasicHostChunkDescriptorTest, BasicHostChunkDescriptorTest) } /* - * Create and immedietly destroy master replica + * Create and immedietly destroy primary replica * Test that it does not result in any network sync */ -class Integ_CreateDestroyMaster +class Integ_CreateDestroyPrimary : public Integ_SimpleTest , public Debug::ReplicaDrillerBus::Handler { @@ -2831,7 +2831,7 @@ public: } }; -TEST_F(Integ_CreateDestroyMaster, CreateDestroyMaster) +TEST_F(Integ_CreateDestroyPrimary, CreateDestroyPrimary) { RunTickLoop([this](int tick)-> TestStatus { @@ -2843,7 +2843,7 @@ TEST_F(Integ_CreateDestroyMaster, CreateDestroyMaster) ConnectDriller(); auto replica = Replica::CreateReplica(nullptr); CreateAndAttachReplicaChunk(replica); - m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); // Destroying replica right away replica->Destroy(); @@ -2894,7 +2894,7 @@ public: LargeChunkWithDefaultsMedium* chunk = CreateAndAttachReplicaChunk(replica); AZ_TEST_ASSERT(chunk); - m_replicaId = m_sessions[sHost].GetReplicaMgr().AddMaster(replica); + m_replicaId = m_sessions[sHost].GetReplicaMgr().AddPrimary(replica); } ~ReplicaACKfeedbackTestFixture() diff --git a/Code/Framework/GridMate/Tests/ReplicaSmall.cpp b/Code/Framework/GridMate/Tests/ReplicaSmall.cpp index c2cd8845da..f1d78d5a18 100644 --- a/Code/Framework/GridMate/Tests/ReplicaSmall.cpp +++ b/Code/Framework/GridMate/Tests/ReplicaSmall.cpp @@ -234,7 +234,7 @@ public: /** * OfflineModeTest verifies that replica chunks are usable without -* an active session, and basically behave as masters. +* an active session, and basically behave as primarys. */ class OfflineModeTest : public UnitTest::GridMateMPTestFixture @@ -297,7 +297,7 @@ public: AZ_TEST_ASSERT(OfflineChunk::s_nInstances == 1); ReplicaChunkPtr chunkPtr = offlineChunk; chunkPtr->Init(ReplicaChunkClassId(OfflineChunk::GetChunkName())); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); offlineChunk->m_data1.Set(5); AZ_TEST_ASSERT(offlineChunk->m_data1.Get() == 5); @@ -315,7 +315,7 @@ public: return true; }); AZ_TEST_ASSERT(offlineChunk->m_data2.Get() == 10); - AZ_TEST_ASSERT(offlineChunk->m_nCallsDataSetChangeCB == 0); // DataSet change CB doesn't get called on master. + AZ_TEST_ASSERT(offlineChunk->m_nCallsDataSetChangeCB == 0); // DataSet change CB doesn't get called on primary. offlineChunk->CallRpc(); AZ_TEST_ASSERT(offlineChunk->m_nCallsRpcHandlerCB == 1); @@ -325,11 +325,11 @@ public: AZ_TEST_ASSERT(strcmp(offlineReplica->GetDebugName(), replicaName) == 0); offlineReplica->AttachReplicaChunk(chunkPtr); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); offlineReplica->DetachReplicaChunk(chunkPtr); - AZ_TEST_ASSERT(chunkPtr->IsMaster()); + AZ_TEST_ASSERT(chunkPtr->IsPrimary()); AZ_TEST_ASSERT(!chunkPtr->IsProxy()); AZ_TEST_ASSERT(OfflineChunk::s_nInstances == 1); @@ -462,7 +462,7 @@ public: ReplicaPeer peer(&rm); AZ_TracePrintf("GridMate", "\n"); - Replica* replica = Replica::CreateReplica("TestMasterReplica"); + Replica* replica = Replica::CreateReplica("TestPrimaryReplica"); ReplicaChunkDescriptorTable::Get().RegisterChunkType(); AZStd::unique_ptr chunk(CreateReplicaChunk()); diff --git a/Code/Framework/Tests/GridMocks.h b/Code/Framework/Tests/GridMocks.h deleted file mode 100644 index 08426bf5a6..0000000000 --- a/Code/Framework/Tests/GridMocks.h +++ /dev/null @@ -1,58 +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 -#include -#include -#include - -namespace UnitTest -{ - class MockSession - : public GridMate::GridSession - { - public: - MockSession(GridMate::SessionService* service) - : GridSession(service) - { - } - - void SetReplicaManager(GridMate::ReplicaManager* replicaManager) - { - m_replicaMgr = replicaManager; - } - - MOCK_METHOD4(CreateRemoteMember, GridMate::GridMember*(const GridMate::string&, GridMate::ReadBuffer&, GridMate::RemotePeerMode, GridMate::ConnectionID)); - MOCK_METHOD1(OnSessionParamChanged, void(const GridMate::GridSessionParam&)); - MOCK_METHOD1(OnSessionParamRemoved, void(const GridMate::string&)); - }; - - class MockSessionService - : public GridMate::SessionService - { - public: - MockSessionService() - : SessionService(GridMate::SessionServiceDesc()) - { - } - - ~MockSessionService() - { - m_activeSearches.clear(); - m_gridMate = nullptr; - } - - MOCK_CONST_METHOD0(IsReady, bool()); - }; -} diff --git a/Code/Framework/Tests/InterestManagerComponentTests.cpp b/Code/Framework/Tests/InterestManagerComponentTests.cpp deleted file mode 100644 index f321609785..0000000000 --- a/Code/Framework/Tests/InterestManagerComponentTests.cpp +++ /dev/null @@ -1,151 +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 "GridMocks.h" - -#include -#include -#include - -#include -#include -#include - -namespace UnitTest -{ - using testing::_; - - class MockInterestManagerEvents - : public AzFramework::InterestManagerEventsBus::Handler - { - public: - MockInterestManagerEvents() - { - BusConnect(); - } - - virtual ~MockInterestManagerEvents() - { - BusDisconnect(); - } - - MOCK_METHOD1(OnInterestManagerActivate, void(GridMate::InterestManager* im)); - MOCK_METHOD1(OnInterestManagerDeactivate, void(GridMate::InterestManager* im)); - }; - - class InterestManagerComponentFixture - : public AllocatorsFixture - { - public: - InterestManagerComponentFixture() - : AllocatorsFixture() - { - - } - - ~InterestManagerComponentFixture() - { - - } - - void SetUp() override - { - AZ::AzSock::Startup(); - - AllocatorsFixture::SetUp(); - AZ::AllocatorInstance::Create(); - m_gridMate = GridMate::GridMateCreate(GridMate::GridMateDesc()); - m_carrier = GridMate::DefaultCarrier::Create(GridMate::CarrierDesc(), m_gridMate); - - m_sessionService = AZStd::make_unique(); - m_gridSession = AZStd::make_unique(m_sessionService.get()); - - m_replicaManagerDesc.m_carrier = m_carrier; - m_replicaManagerDesc.m_myPeerId = AZ::Crc32(testing::UnitTest::GetInstance()->current_test_info()->test_case_name()); - m_replicaManagerDesc.m_roles = GridMate::ReplicaMgrDesc::Role_SyncHost; - m_replicaManager = AZStd::make_unique(); - m_replicaManager->Init(m_replicaManagerDesc); - - m_gridSession->SetReplicaManager(m_replicaManager.get()); - } - - void TearDown() override - { - m_gridSession = nullptr; - m_sessionService = nullptr; - - m_replicaManager->Shutdown(); - m_replicaManager = nullptr; - - m_carrier->Shutdown(); - delete m_carrier; - GridMate::GridMateDestroy(m_gridMate); - AZ::AllocatorInstance::Destroy(); - AllocatorsFixture::TearDown(); - - AZ::AzSock::Cleanup(); - } - - AZStd::unique_ptr m_sessionService; - AZStd::unique_ptr m_gridSession; - - GridMate::IGridMate* m_gridMate; - GridMate::Carrier* m_carrier; - - GridMate::ReplicaMgrDesc m_replicaManagerDesc; - AZStd::unique_ptr m_replicaManager; - }; - - TEST_F(InterestManagerComponentFixture, TestNetworkSessionDeactivate) - { - // Using StrictMock here will ensure that the test fails if any of the events fire (as no EXPECT_CALL has been set). - testing::StrictMock interestManagerEvents; - AzFramework::InterestManagerComponent interestManagerComponent; - - // This will connect the component to the NetBindingSystemEventsBus - interestManagerComponent.Activate(); - - // Ensure that the interest manager component handles receiving OnNetworkSessionDeactivated for a session that was never activated. - // This can happen in the event of a client failing to connect to a host. - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionDeactivated, m_gridSession.get()); - - interestManagerComponent.Deactivate(); - } - - TEST_F(InterestManagerComponentFixture, TestNetworkSessionActivateAndDeactivate) - { - // Using StrictMock here will ensure that the test fails if any of the events fire (as no EXPECT_CALL has been set). - testing::StrictMock interestManagerEvents; - AzFramework::InterestManagerComponent interestManagerComponent; - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - - // This will connect the component to the NetBindingSystemEventsBus - interestManagerComponent.Activate(); - - // Golden path test that the interest manager component behaves as expected under normal conditions - // (receiving OnNetworkSessionActivated followed by OnNetworkSessionDeactivated). - testing::Expectation activationEvent = EXPECT_CALL(interestManagerEvents, OnInterestManagerActivate(_)) - .Times(1); - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionActivated, m_gridSession.get()); - - EXPECT_CALL(interestManagerEvents, OnInterestManagerDeactivate(_)) - .Times(1) - .After(activationEvent); - AzFramework::NetBindingSystemEventsBus::Broadcast( - &AzFramework::NetBindingSystemEvents::OnNetworkSessionDeactivated, m_gridSession.get()); - - interestManagerComponent.Deactivate(); - } -} diff --git a/Code/Framework/Tests/NetBinding.cpp b/Code/Framework/Tests/NetBinding.cpp deleted file mode 100644 index cf2455be0f..0000000000 --- a/Code/Framework/Tests/NetBinding.cpp +++ /dev/null @@ -1,600 +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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace UnitTest -{ -#if 0 - using namespace AZ; - - /** - */ - class NetBindingTestComponent - : public AZ::Component - , public AzFramework::NetBindable - { - friend class NetBindingComponentChunk; - - public: - AZ_COMPONENT(NetBindingTestComponent, "{DE5CF1C0-B4B6-4BB0-86FE-936B400871E0}", AzFramework::NetBindable); - - protected: - class NetChunk - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(NetChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingTestComponent::NetChunk"; } - - bool IsReplicaMigratable() override { return false; } - }; - - /////////////////////////////////////////////////////////////////////// - // NetBindable - GridMate::ReplicaChunkPtr GetNetworkBinding() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::GetNetworkBinding()\n"); - m_chunk = GridMate::CreateReplicaChunk(); - AZ_Assert(m_chunk, "Failed to create NetBindingTestComponent::NetChunk!"); - return m_chunk; - } - - void SetNetworkBinding(GridMate::ReplicaChunkPtr binding) override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::SetNetworkBinding()\n"); - AZ_TEST_ASSERT(binding); - AZ_TEST_ASSERT(binding->GetDescriptor()->GetChunkTypeId() == GridMate::ReplicaChunkClassId(NetChunk::GetChunkName())); - m_chunk = AZStd::static_pointer_cast(binding); - } - - void UnbindFromNetwork() override - { - if (m_chunk) - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::UnbindFromNetwork()\n"); - m_chunk = nullptr; - } - } - /////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////// - // AZ::Component - static void Reflect(AZ::ReflectContext* reflection) - { - AZ::SerializeContext* serializeContext = azrtti_cast(reflection); - if (serializeContext) - { - serializeContext->Class() - ; - } - - // We also need to register the chunk type, and this would be a good time to do so. - GridMate::ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - } - - void Activate() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::Activate()\n"); - } - - void Deactivate() override - { - AZ_TracePrintf("NetBinding", "NetBindingTestComponent::Deactivate()\n"); - UnbindFromNetwork(); - } - /////////////////////////////////////////////////////////////////////// - - AZStd::intrusive_ptr m_chunk; - }; - - /** - * Fakes the behavior of NetBindingSystemContextData on the host side - */ - class FakeNetBindingContextChunk - : public GridMate::ReplicaChunk - { - public: - AZ_CLASS_ALLOCATOR(FakeNetBindingContextChunk, AZ::SystemAllocator, 0); - - static const char* GetChunkName() { return "NetBindingSystemContextData"; } // We are pretending to be a NetBindingSystemContextData - - FakeNetBindingContextChunk() - : m_bindingContextSequence("BindingContextSequence", AzFramework::UnspecifiedNetBindingContextSequence) - { - } - - bool IsReplicaMigratable() override { return true; } - - GridMate::DataSet m_bindingContextSequence; - }; - - /* - * NetBindingSystemComponentLifecycleTest - */ - class NetBindingSystemComponentLifecycleTest - : public GridMate::SessionEventBus::Handler - , public AzFramework::NetBindingHandlerBus::Handler - { - public: - void OnSessionCreated(GridMate::GridSession* session) override - { - if (session == m_session) - { - if (session->IsHost()) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - } - - void OnSessionJoined(GridMate::GridSession* session) override - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - - void OnSessionDelete(GridMate::GridSession* session) - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionDeactivated, session); - m_session = nullptr; - } - } - - void BindToNetwork(GridMate::ReplicaPtr bindTo) override - { - // Verify that BindToNetwork() is not called more than once - AZ_TEST_ASSERT(!m_receivedBindEvent); - m_receivedBindEvent = true; - - // Test that now we should be binding to the network - bool shouldBindToNetwork = false; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(shouldBindToNetwork); - - // Verify that the context sequence is no longer unspecified - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence != AzFramework::UnspecifiedNetBindingContextSequence); - } - - void UnbindFromNetwork() override - { - // Verify that UnbindFromNetwork() is not called more than once - AZ_TEST_ASSERT(!m_receivedUnbindEvent); - m_receivedUnbindEvent = true; - } - - void run() - { - // Setup - AZ::ComponentApplication app; - AZ::ComponentApplication::Descriptor appDesc; - appDesc.m_recordsMode = AZ::Debug::AllocationRecords::RECORD_FULL; - AZ::Entity* systemEntity = app.Create(appDesc); - - app.RegisterComponentDescriptor(AzFramework::NetBindingSystemComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::GameEntityContextComponent::CreateDescriptor()); - - systemEntity->Init(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->Activate(); - AzFramework::NetBindingHandlerBus::Handler::BusConnect(); - - GridMate::GridMateDesc gridMateDesc; - GridMate::IGridMate* gridMate = GridMate::GridMateCreate(gridMateDesc); - GridMate::GridMateAllocatorMP::Descriptor allocDesc; - allocDesc.m_stackRecordLevels = 15; - allocDesc.m_custom = &AZ::AllocatorInstance::Get(); - AZ::AllocatorInstance::Create(allocDesc); - if (AZ::AllocatorInstance::Get().GetRecords()) - { - AZ::AllocatorInstance::Get().GetRecords()->SetMode(AZ::Debug::AllocationRecords::RECORD_FULL); - } - GridMate::StartGridMateService(gridMate, GridMate::SessionServiceDesc()); - GridMate::SessionEventBus::Handler::BusConnect(gridMate); - - // Test offline behavior - { - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Test host-side behavior - { - m_receivedBindEvent = m_receivedUnbindEvent = false; - - // Host a session - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - m_session = gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - int nFrame = 0; - while (m_session) - { - if (nFrame == 10) - { - // Verify that BindToNetwork() has been called - AZ_TEST_ASSERT(m_receivedBindEvent); - - // Verify that we have a valid context sequence - AzFramework::NetBindingContextSequence contextSequence1 = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence1, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence1 != AzFramework::UnspecifiedNetBindingContextSequence); - - EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext); - - // Verify that the context sequence was incremented - AzFramework::NetBindingContextSequence contextSequence2 = contextSequence1; - EBUS_EVENT_RESULT(contextSequence2, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence2 != AzFramework::UnspecifiedNetBindingContextSequence); - AZ_TEST_ASSERT(contextSequence2 > contextSequence1); - - m_session->Leave(false); - } - - app.Tick(); - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - nFrame++; - } - - // Verify that we should no longer bind to the network - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - // Verify that the context sequence was reset to unspecified - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Test nonhost-side behavior by faking the behavior on the host side and then joining the host session. - { - m_receivedBindEvent = m_receivedUnbindEvent = false; - - // Host a session - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - GridMate::GridSession* hostSession = gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - // Add the fake context replica on the host and set the context sequence to 1 - GridMate::ReplicaPtr replica = GridMate::Replica::CreateReplica("Potato"); - FakeNetBindingContextChunk* contextChunk = GridMate::CreateReplicaChunk(); - replica->AttachReplicaChunk(contextChunk); - while (!hostSession->IsReady()) - { - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - hostSession->GetReplicaMgr()->AddMaster(replica); - contextChunk->m_bindingContextSequence.Set(1); - - int nFrame = 0; - while (m_session) - { - if (nFrame == 10) - { - // Join the hosted session - GridMate::SessionIdInfo sessionInfo; - sessionInfo.m_sessionId = hostSession->GetId(); - m_session = gridMate->GetMultiplayerService()->JoinSession(&sessionInfo, GridMate::JoinParams(), carrierDesc); - } - - if (nFrame == 20) - { - // Verify that BindToNetwork() has been called - AZ_TEST_ASSERT(m_receivedBindEvent); - - // Verify that we have a valid context sequence - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence == contextChunk->m_bindingContextSequence.Get()); - - // Simulate a context switch on the host - contextChunk->m_bindingContextSequence.Set(contextChunk->m_bindingContextSequence.Get() + 1); - } - - if (nFrame == 30) - { - // Verify that the context sequence was incremented - AzFramework::NetBindingContextSequence contextSequence = AzFramework::UnspecifiedNetBindingContextSequence; - EBUS_EVENT_RESULT(contextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(contextSequence == contextChunk->m_bindingContextSequence.Get()); - - hostSession->Leave(false); - } - - app.Tick(); - gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - nFrame++; - } - - // Verify that we should no longer bind to the network - bool shouldBindToNetwork = true; - EBUS_EVENT_RESULT(shouldBindToNetwork, AzFramework::NetBindingSystemBus, ShouldBindToNetwork); - AZ_TEST_ASSERT(!shouldBindToNetwork); - - // Verify that the context sequence was reset to unspecified - AzFramework::NetBindingContextSequence offlineContextSequence = 0xBADF00D; - EBUS_EVENT_RESULT(offlineContextSequence, AzFramework::NetBindingSystemBus, GetCurrentContextSequence); - AZ_TEST_ASSERT(offlineContextSequence == AzFramework::UnspecifiedNetBindingContextSequence); - } - - // Clean up - GridMate::SessionEventBus::Handler::BusDisconnect(); - GridMate::GridMateDestroy(gridMate); - AZ::AllocatorInstance::Destroy(); - AzFramework::NetBindingHandlerBus::Handler::BusDisconnect(); - app.Destroy(); - } - - static const int HOST_PORT = 5000; - - GridMate::GridSession* m_session; - bool m_receivedBindEvent; - bool m_receivedUnbindEvent; - }; - - /* - * NetBindingFeatureTest (requires two instances) - */ - class NetBindingFeatureTest - : public GridMate::SessionEventBus::Handler - { - public: - void OnSessionCreated(GridMate::GridSession* session) override - { - if (session == m_session) - { - if (session->IsHost()) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - } - - void OnSessionJoined(GridMate::GridSession* session) override - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionActivated, session); - } - } - - void OnSessionDelete(GridMate::GridSession* session) - { - if (session == m_session) - { - EBUS_EVENT(AzFramework::NetBindingSystemBus, OnNetworkSessionDeactivated, session); - m_session = nullptr; - } - } - - void OnGridSearchComplete(GridMate::GridSearch* results) override - { - if (results == m_search) - { - GridMate::CarrierDesc carrierDesc; - carrierDesc.m_enableDisconnectDetection = true; - - // Create an entity before we get in the session - AZ_TracePrintf("NetBinding", "Spawning master entity...\n"); - AZ::Entity* newEntity = nullptr; - newEntity = aznew Entity; - newEntity->CreateComponent(); - newEntity->CreateComponent(); - newEntity->Init(); - newEntity->Activate(); - m_entities.push_back(newEntity); - - if (results->GetNumResults() == 0) - { - // Host a session instead - GridMate::LANSessionParams sessionParams; - sessionParams.m_numPublicSlots = 10; - sessionParams.m_flags = 0; - sessionParams.m_port = HOST_PORT; - sessionParams.m_params[sessionParams.m_numParams].m_id = "filter"; - sessionParams.m_params[sessionParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - sessionParams.m_numParams++; - m_session = m_gridMate->GetMultiplayerService()->HostSession(&sessionParams, carrierDesc); - - m_search->Release(); - } - else - { - // Join the session - GridMate::JoinParams joinParams; - m_session = m_gridMate->GetMultiplayerService()->JoinSession(results->GetResult(0), joinParams, carrierDesc); - } - m_search = nullptr; - } - } - - void OnMemberJoined(GridMate::GridSession* session, GridMate::GridMember* member) override - { - if (session == m_session) - { - if (session->IsHost()) - { - if (member != session->GetMyMember()) - { - // Spawn an entity after session creation - AZ_TracePrintf("NetBinding", "Spawning master entity...\n"); - AZ::Entity* newEntity = nullptr; - EBUS_EVENT_RESULT(newEntity, AzFramework::GameEntityContextRequestBus, CreateGameEntity, "ReplicatedEntity2"); - newEntity->CreateComponent(); - newEntity->CreateComponent(); - newEntity->Init(); - newEntity->Activate(); - m_entities.push_back(newEntity); - } - } - } - } - - void run() - { - m_gridMate = nullptr; - m_session = nullptr; - - AZ::ComponentApplication app; - AZ::ComponentApplication::Descriptor appDesc; - AZ::Entity* systemEntity = app.Create(appDesc); - - app.RegisterComponentDescriptor(AzFramework::NetBindingSystemComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::NetBindingComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(NetBindingTestComponent::CreateDescriptor()); - app.RegisterComponentDescriptor(AzFramework::GameEntityContextComponent::CreateDescriptor()); - - systemEntity->Init(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->CreateComponent(); - systemEntity->Activate(); - - GridMate::GridMateDesc gridMateDesc; - m_gridMate = GridMate::GridMateCreate(gridMateDesc); - - GridMate::GridMateAllocatorMP::Descriptor allocDesc; - allocDesc.m_custom = &AZ::AllocatorInstance::Get(); - AZ::AllocatorInstance::Create(allocDesc); - - GridMate::StartGridMateService(m_gridMate, GridMate::SessionServiceDesc()); - - GridMate::SessionEventBus::Handler::BusConnect(m_gridMate); - - // Search for an existing session - // If a session is not found, we will host a session from within the search callback. - { - GridMate::LANSearchParams searchParams; - searchParams.m_serverPort = HOST_PORT; - searchParams.m_params[searchParams.m_numParams].m_id = "filter"; - searchParams.m_params[searchParams.m_numParams].m_value = GridMate::Utils::GetMachineAddress(); - searchParams.m_params[searchParams.m_numParams].m_op = GridMate::GridSessionSearchOperators::SSO_OPERATOR_EQUAL; - searchParams.m_numParams++; - m_search = m_gridMate->GetMultiplayerService()->StartGridSearch(&searchParams); - - while (m_search) - { - m_gridMate->Update(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - } - - // Tick for a while - //static int nTicks = 100; - for (int i = 0; m_session; ++i) - { - if (m_session->IsHost()) - { - if (i > 4000 && m_session->GetNumberOfMembers() == 1) - { - m_session->Leave(false); - } - } - - m_gridMate->Update(); - app.Tick(); - AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(10)); - } - - GridMate::SessionEventBus::Handler::BusDisconnect(); - - GridMate::GridMateDestroy(m_gridMate); - - AZ::AllocatorInstance::Destroy(); - - for (AZ::Entity* entity : m_entities) - { - AzFramework::EntityContextId contextId = AzFramework::EntityContextId::CreateNull(); - EBUS_EVENT_ID_RESULT(contextId, entity->GetId(), AzFramework::EntityIdContextQueryBus, GetOwningContextId); - if (contextId.IsNull()) - { - delete entity; - } - else - { - EBUS_EVENT(AzFramework::GameEntityContextRequestBus, DestroyGameEntity, entity); - } - } - - app.Destroy(); - } - - static const int HOST_PORT = 6000; - - GridMate::IGridMate* m_gridMate; - GridMate::GridSession* m_session; - GridMate::GridSearch* m_search; - AZStd::fixed_vector m_entities; - }; -#endif -} - -AZ_TEST_SUITE(NetBinding) -//AZ_TEST(UnitTest::NetBindingSystemComponentLifecycleTest) -//AZ_TEST(UnitTest::NetBindingFeatureTest) -AZ_TEST_SUITE_END diff --git a/Code/Framework/Tests/NetBindingMocks.h b/Code/Framework/Tests/NetBindingMocks.h deleted file mode 100644 index 3973fe670d..0000000000 --- a/Code/Framework/Tests/NetBindingMocks.h +++ /dev/null @@ -1,335 +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. -* -*/ - -#ifndef AZCORE_UNITTEST_NETBINDINGMOCKS_H -#define AZCORE_UNITTEST_NETBINDINGMOCKS_H - -#include -#include -#include -#include -#include -#include -#include - -namespace UnitTest -{ - class MockGameEntityContext - : public AzFramework::GameEntityContextRequestBus::Handler - , public AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler - { - public: - MockGameEntityContext() - { - AzFramework::GameEntityContextRequestBus::Handler::BusConnect(); - AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler::BusConnect(); - } - - ~MockGameEntityContext() - { - AzFramework::SliceGameEntityOwnershipServiceRequestBus::Handler::BusDisconnect(); - AzFramework::GameEntityContextRequestBus::Handler::BusDisconnect(); - } - - MOCK_METHOD3(InstantiateDynamicSlice, AzFramework::SliceInstantiationTicket(const AZ::Data::Asset&, const AZ::Transform&, const AZ::IdUtils::Remapper::IdMapper&)); - MOCK_METHOD0(GetGameEntityContextId, AzFramework::EntityContextId()); - MOCK_METHOD0(GetGameEntityContextInstance, AzFramework::EntityContext*()); - MOCK_METHOD1(CreateGameEntity, AZ::Entity*(const char*)); - MOCK_METHOD1(AddGameEntity, void (AZ::Entity*)); - MOCK_METHOD1(DestroyGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DestroyGameEntityAndDescendants, void (const AZ::EntityId&)); - MOCK_METHOD1(ActivateGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DeactivateGameEntity, void (const AZ::EntityId&)); - MOCK_METHOD1(DestroyDynamicSliceByEntity, bool (const AZ::EntityId&)); - MOCK_METHOD2(LoadFromStream, bool (AZ::IO::GenericStream&, bool)); - MOCK_METHOD0(ResetGameContext, void ()); - MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&)); - MOCK_METHOD1(DestroySliceByEntity, bool(const AZ::EntityId&)); - MOCK_METHOD1(CreateGameEntityForBehaviorContext, AzFramework::BehaviorEntity (const char *)); - MOCK_METHOD1(CancelDynamicSliceInstantiation, void (const AzFramework::SliceInstantiationTicket &)); - }; - - class MockNetBindingSystemContextData - : public AzFramework::NetBindingSystemContextData - { - public: - AZ_CLASS_ALLOCATOR(MockNetBindingSystemContextData, AZ::SystemAllocator, 0); - - static const char* GetChunkName() - { - return "MockNetBindingSystemContextData"; - } - - MOCK_METHOD1(OnAttachedToReplica, void (GridMate::Replica*)); - MOCK_METHOD1(OnDetachedFromReplica, void (GridMate::Replica*)); - MOCK_METHOD1(UpdateChunk, void (const GridMate::ReplicaContext&)); - MOCK_METHOD1(UpdateFromChunk, void (const GridMate::ReplicaContext&)); - MOCK_METHOD2(AcceptChangeOwnership, bool (GridMate::PeerId, const GridMate::ReplicaContext&)); - MOCK_METHOD1(OnReplicaChangeOwnership, void (const GridMate::ReplicaContext&)); - MOCK_METHOD0(IsUpdateFromReplicaEnabled, bool ()); - MOCK_CONST_METHOD1(ShouldSendToPeer, bool (GridMate::ReplicaPeer*)); - MOCK_METHOD1(CalculateDirtyDataSetMask, AZ::u32 (GridMate::MarshalContext&)); - MOCK_METHOD1(OnDataSetChanged, void (const GridMate::DataSetBase&)); - MOCK_METHOD2(Marshal, void (GridMate::MarshalContext&, AZ::u32)); - MOCK_METHOD2(Unmarshal, void (GridMate::UnmarshalContext&, AZ::u32)); - MOCK_METHOD0(IsReplicaMigratable, bool ()); - MOCK_METHOD0(IsBroadcast, bool ()); - MOCK_METHOD1(OnReplicaActivate, void (const GridMate::ReplicaContext&)); - MOCK_METHOD1(OnReplicaDeactivate, void (const GridMate::ReplicaContext&)); - - /** - * \brief Helper method for GoogleMock to call NetBindingSystemContextData::OnReplicaActivate - */ - void Base_OnReplicaActivate(const GridMate::ReplicaContext& rc) - { - NetBindingSystemContextData::OnReplicaActivate(rc); - } - - MOCK_METHOD0(GetReplicaManager, GridMate::ReplicaManager* ()); - MOCK_METHOD0(ShouldBindToNetwork, bool ()); - }; - - class MockReplicaManager - : public GridMate::ReplicaManager - { - public: - MOCK_METHOD2(OnIncomingConnection, void (GridMate::Carrier*, GridMate::ConnectionID)); - MOCK_METHOD3(OnFailedToConnect, void (GridMate::Carrier*, GridMate::ConnectionID, GridMate::CarrierDisconnectReason)); - MOCK_METHOD3(OnDriverError, void (GridMate::Carrier*, GridMate::ConnectionID, const GridMate::DriverError&)); - MOCK_METHOD3(OnSecurityError, void (GridMate::Carrier*, GridMate::ConnectionID, const GridMate::SecurityError&)); - MOCK_METHOD1(Destroy, bool (GridMate::Replica*)); - MOCK_METHOD2(GetReplicaContext, void (const GridMate::Replica*, GridMate::ReplicaContext&)); - MOCK_METHOD2(OnConnectionEstablished, void (GridMate::Carrier*, GridMate::ConnectionID)); - MOCK_METHOD3(OnDisconnect, void (GridMate::Carrier*, GridMate::ConnectionID, GridMate::CarrierDisconnectReason)); - MOCK_METHOD3(OnRateChange, void (GridMate::Carrier*, GridMate::ConnectionID, AZ::u32)); - MOCK_METHOD1(FindReplica, GridMate::ReplicaPtr (GridMate::ReplicaId)); - }; - - class MockAssetHandler - : public AZ::Data::AssetHandler - { - public: - AZ_CLASS_ALLOCATOR(MockAssetHandler, AZ::SystemAllocator, 0) - - MOCK_METHOD2(CreateAsset, AZ::Data::AssetPtr (const AZ::Data::AssetId&, const AZ::Data::AssetType&)); - MOCK_METHOD3(LoadAssetData, AZ::Data::AssetHandler::LoadResult ( - const AZ::Data::Asset&, - AZStd::shared_ptr, - const AZ::Data::AssetFilterCB&)); - MOCK_METHOD2(SaveAssetData, bool (const AZ::Data::Asset&, AZ::IO::GenericStream*)); - MOCK_METHOD3(InitAsset, void (const AZ::Data::Asset&, bool, bool)); - MOCK_METHOD1(DestroyAsset, void (AZ::Data::AssetPtr)); - MOCK_METHOD1(GetHandledAssetTypes, void (AZStd::vector&)); - MOCK_CONST_METHOD1(CanHandleAsset, bool (const AZ::Data::AssetId&)); - }; - - class MockAsset - : public AZ::DynamicSliceAsset - { - public: - AZ_RTTI(MockAsset, "{78ABC204-452E-4621-A552-F04D3ABF1690}", DynamicSliceAsset); - - MockAsset(const AZ::Data::AssetId& assetId = AZ::Data::AssetId()) - : DynamicSliceAsset(assetId) - { - } - - ~MockAsset() = default; - }; - - class MockSliceReference - : public AZ::SliceComponent::SliceReference - { - public: - using SliceReference::SliceReference; - - MOCK_METHOD1(CreateInstance, AZ::SliceComponent::SliceInstance*(const AZ::IdUtils::Remapper::IdMapper&)); - MOCK_METHOD2(CloneInstance, AZ::SliceComponent::SliceInstance*(AZ::SliceComponent::SliceInstance*, AZ::SliceComponent::EntityIdToEntityIdMap&)); - MOCK_METHOD1(FindInstance, AZ::SliceComponent::SliceInstance*(const AZ::SliceComponent::SliceInstanceId&)); - MOCK_METHOD1(RemoveInstance, bool(AZ::SliceComponent::SliceInstance*)); - MOCK_METHOD3(RemoveEntity, bool(AZ::EntityId, bool, AZ::SliceComponent::SliceInstance*)); - MOCK_CONST_METHOD0(GetInstances, const AZ::SliceComponent::SliceReference::SliceInstances&()); - MOCK_CONST_METHOD0(GetSliceAsset, const AZ::Data::Asset& ()); - MOCK_CONST_METHOD0(GetSliceComponent, AZ::SliceComponent*()); - MOCK_CONST_METHOD0(IsInstantiated, bool ()); - MOCK_CONST_METHOD3(GetInstanceEntityAncestry, bool(const AZ::EntityId&, AZ::SliceComponent::EntityAncestorList&, AZ::u32)); - MOCK_METHOD0(ComputeDataPatch, void()); - }; - - class MockSliceInstance - : public AZ::SliceComponent::SliceInstance - { - public: - using SliceInstance::SliceInstance; - - void SetMockInstantiatedContainer(AZ::SliceComponent::InstantiatedContainer* newContainer) - { - m_instantiated = newContainer; - - for (AZ::Entity* entity : m_instantiated->m_entities) - { - m_entityIdToBaseCache.insert(AZStd::make_pair(entity->GetId(), entity->GetId())); - } - - for (AZ::Entity* entity : m_instantiated->m_entities) - { - m_baseToNewEntityIdMap.insert(AZStd::make_pair(entity->GetId(), entity->GetId())); - } - } - - MOCK_CONST_METHOD0(GetInstantiated, const AZ::SliceComponent::InstantiatedContainer*()); - MOCK_CONST_METHOD0(GetDataPatch, const AZ::DataPatch&()); - MOCK_CONST_METHOD0(GetDataFlags, const AZ::SliceComponent::DataFlagsPerEntity&()); - MOCK_METHOD0(GetDataFlags, AZ::SliceComponent::DataFlagsPerEntity&()); - MOCK_CONST_METHOD0(GetEntityIdMap, const AZ::SliceComponent::EntityIdToEntityIdMap& ()); - MOCK_CONST_METHOD0(GetEntityIdToBaseMap, const AZ::SliceComponent::EntityIdToEntityIdMap& ()); - MOCK_CONST_METHOD0(GetId, const AZ::SliceComponent::SliceInstanceId& ()); - MOCK_CONST_METHOD0(GetMetadataEntity, AZ::Entity* ()); - }; - - class MockEntity - : public AZ::Entity - { - public: - ~MockEntity() override {} - - MOCK_METHOD0(Init, void ()); - MOCK_METHOD0(Activate, void ()); - MOCK_METHOD0(Deactivate, void ()); - - /** - * \brief Helper method for GoogleMock to call base class method - */ - void Base_Init() - { - Entity::Init(); - } - - /** - * \brief Helper method for GoogleMock to mark an entity as activated - */ - void Base_Activate() - { - m_state = State::Active; - } - - /** - * \brief Helper method for GoogleMock to mark an entity as deactivated - */ - void Base_Deactivate() - { - m_state = State::Init; - } - }; - - class MockComponentApplication - : public AZ::ComponentApplicationBus::Handler - { - public: - MockComponentApplication() - { - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - } - ~MockComponentApplication() - { - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } - - AZStd::vector m_mockEntities; - - bool AddEntity(AZ::Entity* entity) override - { - const auto it = AZStd::find(m_mockEntities.begin(), m_mockEntities.end(), entity); - if (it == m_mockEntities.end()) - { - m_mockEntities.push_back(entity); - return true; - } - - return false; - } - - AZ::Entity* FindEntity(const AZ::EntityId& id) override - { - const auto it = AZStd::find_if(m_mockEntities.begin(), m_mockEntities.end(), [id](AZ::Entity* entity) - { - return entity->GetId() == id; - }); - - if (it != m_mockEntities.end()) - { - return *it; - } - return nullptr; - } - - MOCK_METHOD0(Destroy, void ()); - MOCK_METHOD1(RegisterComponentDescriptor, void (const AZ::ComponentDescriptor*)); - MOCK_METHOD1(UnregisterComponentDescriptor, void (const AZ::ComponentDescriptor*)); - MOCK_METHOD1(RegisterEntityAddedEventHandler, void(AZ::EntityAddedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityRemovedEventHandler, void(AZ::EntityRemovedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityActivatedEventHandler, void(AZ::EntityActivatedEvent::Handler&)); - MOCK_METHOD1(RegisterEntityDeactivatedEventHandler, void(AZ::EntityDeactivatedEvent::Handler&)); - MOCK_METHOD1(SignalEntityActivated, void(AZ::Entity*)); - MOCK_METHOD1(SignalEntityDeactivated, void(AZ::Entity*)); - MOCK_METHOD1(RemoveEntity, bool (AZ::Entity*)); - MOCK_METHOD1(DeleteEntity, bool (const AZ::EntityId&)); - MOCK_METHOD1(GetEntityName, AZStd::string (const AZ::EntityId&)); - MOCK_METHOD1(EnumerateEntities, void (const ComponentApplicationRequests::EntityCallback&)); - MOCK_METHOD0(GetApplication, AZ::ComponentApplication* ()); - MOCK_METHOD0(GetSerializeContext, AZ::SerializeContext* ()); - MOCK_METHOD0(GetBehaviorContext, AZ::BehaviorContext* ()); - MOCK_METHOD0(GetJsonRegistrationContext, AZ::JsonRegistrationContext* ()); - MOCK_CONST_METHOD0(GetAppRoot, const char* ()); - MOCK_CONST_METHOD0(GetEngineRoot, const char* ()); - MOCK_CONST_METHOD0(GetExecutableFolder, const char* ()); - MOCK_METHOD0(GetDrillerManager, AZ::Debug::DrillerManager* ()); - MOCK_METHOD0(GetTickDeltaTime, float ()); - MOCK_METHOD0(GetTimeAtCurrentTick, AZ::ScriptTimePoint ()); - MOCK_METHOD1(Tick, void (float)); - MOCK_METHOD0(TickSystem, void ()); - MOCK_CONST_METHOD0(GetRequiredSystemComponents, AZ::ComponentTypeList ()); - MOCK_METHOD1(ResolveModulePath, void (AZ::OSString&)); - MOCK_METHOD0(RegisterCoreComponents, void ()); - MOCK_METHOD1(Reflect, void (AZ::ReflectContext*)); - MOCK_CONST_METHOD1(QueryApplicationType, void(AZ::ApplicationTypeQuery&)); - }; - - class MockBindingComponent - : public AZ::Component - , public AzFramework::NetBindingHandlerBus::Handler - { - public: - AZ_COMPONENT(MockBindingComponent, "{8393809A-3256-4865-97A9-1CCA43073B4A}", NetBindingHandlerInterface); - - static void Reflect(AZ::ReflectContext*) {} - - MOCK_METHOD0(Init, void ()); - MOCK_METHOD0(Activate, void ()); - MOCK_METHOD0(Deactivate, void ()); - MOCK_METHOD1(ReadInConfig, bool (const AZ::ComponentConfig*)); - MOCK_CONST_METHOD1(WriteOutConfig, bool (AZ::ComponentConfig*)); - MOCK_METHOD1(BindToNetwork, void (GridMate::ReplicaPtr)); - MOCK_METHOD0(UnbindFromNetwork, void ()); - MOCK_METHOD0(IsEntityBoundToNetwork, bool ()); - MOCK_METHOD0(IsEntityAuthoritative, bool ()); - MOCK_METHOD0(MarkAsLevelSliceEntity, void ()); - MOCK_METHOD1(SetSliceInstanceId, void (const AZ::SliceComponent::SliceInstanceId&)); - MOCK_METHOD1(SetReplicaPriority, void (GridMate::ReplicaPriority)); - MOCK_METHOD1(RequestEntityChangeOwnership, void (GridMate::PeerId)); - MOCK_CONST_METHOD0(GetReplicaPriority, GridMate::ReplicaPriority ()); - }; -} - -#endif // AZCORE_UNITTEST_NETBINDINGMOCKS_H diff --git a/Code/Framework/Tests/NetBindingSystemImplTest.cpp b/Code/Framework/Tests/NetBindingSystemImplTest.cpp deleted file mode 100644 index 790ef1cd72..0000000000 --- a/Code/Framework/Tests/NetBindingSystemImplTest.cpp +++ /dev/null @@ -1,605 +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 -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include "NetBindingMocks.h" -#include -#include -#include -#include - -namespace UnitTest -{ - using namespace AZ; - using namespace AzFramework; - using namespace GridMate; - - class NetBindingWithSlicesTest - : public ScopedAllocatorSetupFixture - { - public: - const NetBindingContextSequence k_fakeContextSeq = 1; - const AZ::SliceComponent::SliceInstanceId k_fakeSliceInstanceId = Uuid::CreateRandom(); - const AZ::SliceComponent::SliceInstanceId k_fakeSliceInstanceId_Another = Uuid::CreateRandom(); - - SliceInstantiationTicket m_sliceTicket = SliceInstantiationTicket(EntityContextId::CreateName("Test"), 1); - const Data::AssetId k_fakeAssetId = Data::AssetId(Uuid::CreateRandom(), 0); - - const EntityId k_fakeEntityId_One = EntityId(9001); - const ReplicaId k_repId_One = 1001; - const EntityId k_fakeEntityId_Two = EntityId(9002); - const ReplicaId k_repId_Two = 1002; - - AZStd::unique_ptr m_netBindingImpl; - AZStd::unique_ptr m_componentApplication; - AZStd::unique_ptr m_applicationContext; - - AZStd::unique_ptr m_gameEntityMock; - AZStd::unique_ptr m_replicaManagerMock; - ReplicaPtr m_replicaMock; - - ComponentDescriptor* m_netBindingSystemComponentDescriptor = nullptr; - - AZStd::intrusive_ptr m_contextChunkMock; - - MockAssetHandler* m_myAssetHandlerAndCatalog = nullptr; // owned by AssetManager - AZStd::unique_ptr m_fakeAsset; - - const float k_wayOverSliceTimeout = NetBindingSystemImpl::s_sliceBindingTimeout.count() * 2.f; - const float k_smallStep = 0.1f; - - void SetUpFakeAssetManager() - { - using namespace testing; - - const Data::AssetManager::Descriptor desc; - Data::AssetManager::Create(desc); - - m_myAssetHandlerAndCatalog = aznew NiceMock; - - ON_CALL(*m_myAssetHandlerAndCatalog, CreateAsset(_, _)) - .WillByDefault(Invoke([this](const Data::AssetId&, const Data::AssetType&) -> Data::AssetPtr - { - m_fakeAsset = AZStd::make_unique>(k_fakeAssetId); - return m_fakeAsset.get(); - })); - - ON_CALL(*m_myAssetHandlerAndCatalog, DestroyAsset(_)) - .WillByDefault(Invoke([this](const Data::AssetPtr asset) - { - EXPECT_EQ(asset, m_fakeAsset.get()); - m_fakeAsset.reset(); - })); - - Data::AssetManager::Instance().RegisterHandler(m_myAssetHandlerAndCatalog, AzTypeInfo::Uuid()); - Data::AssetManager::Instance().RegisterHandler(m_myAssetHandlerAndCatalog, AzTypeInfo::Uuid()); - } - - void SetUp() override - { - using namespace testing; - - m_applicationContext.reset(aznew SerializeContext()); - - AllocatorInstance::Create(); - AllocatorInstance::Create(); - - DefaultValue::Set(m_sliceTicket); - - m_gameEntityMock = AZStd::make_unique>(); - m_componentApplication = AZStd::make_unique>(); - - ON_CALL(*m_componentApplication, GetSerializeContext()) - .WillByDefault(Invoke([this]() - { - return m_applicationContext.get(); - })); - - ON_CALL(*m_gameEntityMock, GetGameEntityContextId()) - .WillByDefault(Return(EntityContextId::CreateRandom())); - - m_netBindingSystemComponentDescriptor = NetBindingSystemComponent::CreateDescriptor(); - - ReplicaChunkDescriptorTable::Get().RegisterChunkType(); - m_contextChunkMock.reset(CreateReplicaChunk>()); - - ON_CALL(*m_contextChunkMock, ShouldBindToNetwork()) - .WillByDefault(Return(true)); - - m_replicaManagerMock = AZStd::make_unique>(); - - ON_CALL(*m_contextChunkMock, GetReplicaManager()) - .WillByDefault(Invoke([this]() - { - return m_replicaManagerMock.get(); - })); - - m_replicaMock = Replica::CreateReplica("unittest"); - - ON_CALL(*m_replicaManagerMock, FindReplica(_)) - .WillByDefault(Invoke([this](ReplicaId id) -> ReplicaPtr - { - AZ_UNUSED(id); - return m_replicaMock; - })); - - ON_CALL(*m_contextChunkMock, OnReplicaActivate(_)) - .WillByDefault(Invoke(m_contextChunkMock.get(), &MockNetBindingSystemContextData::Base_OnReplicaActivate)); - - m_netBindingImpl = AZStd::make_unique(); - m_netBindingImpl->Init(); - - m_contextChunkMock->OnReplicaActivate(ReplicaContext(nullptr, TimeContext())); - - SetUpFakeAssetManager(); - } - - void TearDown() override - { - Data::AssetManager::Destroy(); - - m_replicaMock.reset(); - m_replicaManagerMock.reset(); - m_contextChunkMock.reset(); - - m_fakeAsset.reset(); - m_netBindingImpl->Shutdown(); - m_netBindingImpl.reset(); - - ReplicaChunkDescriptorTable::Get().UnregisterReplicaChunkDescriptor(ReplicaChunkClassId(MockNetBindingSystemContextData::GetChunkName())); - - m_netBindingSystemComponentDescriptor->ReleaseDescriptor(); - - m_componentApplication.reset(); - m_gameEntityMock.reset(); - - AllocatorInstance::Destroy(); - AllocatorInstance::Destroy(); - - m_applicationContext.reset(); - } - }; - - TEST_F(NetBindingWithSlicesTest, SameSliceInstanceId_InstantiateDynamicSlice_CallOnce) - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, InstantiateDynamicSlice(_, _, _)) - .Times(1); - EXPECT_CALL(*m_gameEntityMock, CancelDynamicSliceInstantiation(_)) - .Times(1); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // this should kick off NetBindingSystemImpl::ProcessBindRequests - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(NetBindingWithSlicesTest, DifferentSliceInstanceId_InstantiateDynamicSlice_CalledTwice) - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, InstantiateDynamicSlice(_, _, _)) - .Times(2); - EXPECT_CALL(*m_gameEntityMock, CancelDynamicSliceInstantiation(_)) - .Times(2); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId_Another; // different slice entity - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // this should kick off NetBindingSystemImpl::ProcessBindRequests - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(NetBindingWithSlicesTest, AssetManagerDestroyed_InstantiateDynamicSlice_NotCalled) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - Data::AssetManager::Destroy(); - - // this should kick off NetBindingSystemImpl::ProcessBindRequests, but InstantiateDynamicSlice will not be called - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - class ExtendedBindingWithSlicesTest - : public NetBindingWithSlicesTest - { - public: - void SetUp() override - { - NetBindingWithSlicesTest::SetUp(); - } - - void TearDown() override - { - using namespace testing; - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_One)) - .Times(AtMost(1)); - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(AtMost(1)); - - NetBindingWithSlicesTest::TearDown(); - } - - class InstantiateMockSlice - { - public: - explicit InstantiateMockSlice(ExtendedBindingWithSlicesTest* parent) - { - using namespace testing; - - m_mockSliceRef = AZStd::make_unique(); - m_mockSliceInstance = AZStd::make_unique(); - - // container owns the entities and will delete them - auto mockContainer = AZStd::make_unique(); - - auto binding1 = AZStd::make_unique>(); - mockContainer->m_entities.push_back(CreateMockEntity(parent->k_fakeEntityId_One, binding1.release())); - - auto binding2 = AZStd::make_unique>(); - mockContainer->m_entities.push_back(CreateMockEntity(parent->k_fakeEntityId_Two, binding2.release())); - - m_mockSliceInstance->SetMockInstantiatedContainer(mockContainer.release()); - - SliceComponent::SliceInstanceAddress sliceInstanceAddress(m_mockSliceRef.get(), m_mockSliceInstance.get()); - - // This will pass our mock slice to NetBindingSystem - EBUS_EVENT_ID(parent->m_sliceTicket, SliceInstantiationResultBus, OnSlicePreInstantiate, parent->k_fakeAssetId, sliceInstanceAddress); - EBUS_EVENT_ID(parent->m_sliceTicket, SliceInstantiationResultBus, OnSliceInstantiated, parent->k_fakeAssetId, sliceInstanceAddress); - } - - Entity* CreateMockEntity(const EntityId& id, Component* optional = nullptr) - { - using namespace testing; - - auto mock = AZStd::make_unique>(); - mock->SetId(EntityId(id)); - if (optional) - { - mock->AddComponent(optional); // entity owns the component - } - ON_CALL(*mock, Init()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Init)); - mock->Init(); - - ON_CALL(*mock, Activate()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Activate)); - - ON_CALL(*mock, Deactivate()) - .WillByDefault(Invoke(mock.get(), &MockEntity::Base_Deactivate)); - - return mock.release(); - } - - AZStd::unique_ptr m_mockSliceRef; - AZStd::unique_ptr m_mockSliceInstance; - }; - - AZStd::unique_ptr m_slice; - - void CreateMockSlice() - { - m_slice = AZStd::make_unique(this); - } - }; - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_EntitiesThatWerentBounded_StayDeactivated) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(0); - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - // Now it should time out the slice handler and the second entity should remain deactivated since we didn't give binding request for it - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_SpawnSecondEntity_AfterLongDelay_InSameSlicenInstance) - { - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(0); - - // This should not trigger removal of the second entity yet - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - EXPECT_CALL(*mock2, Activate()). - Times(1); - - // This should give net binding system time to bind the second entity - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - // Let the slice timeout, this should lead to no destruction since both entities ought to have been bound by now - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_DespawnLastEntity_DespawnWholeSliceAfterTimeout) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - // This should not trigger removal of the second entity yet - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - EXPECT_CALL(*mock1, Deactivate()). - Times(1); - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_One, k_fakeSliceInstanceId); - - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_One)) - .Times(1); - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_DespawnLastEntityBeforeSliceInstantiation_DespawnWholeSlice) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_One, k_fakeSliceInstanceId); - - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(0); - - auto halfTimeoutInSeconds = AZStd::chrono::seconds(NetBindingSystemImpl::s_sliceBindingTimeout).count() * 10.f; - EBUS_EVENT(AZ::TickBus, OnTick, halfTimeoutInSeconds, AZ::ScriptTimePoint()); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, ActiveSlice_ReuseEntity) - { - EXPECT_CALL(*m_gameEntityMock, DestroyGameEntity(k_fakeEntityId_Two)) - .Times(0); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - CreateMockSlice(); - - MockEntity* mock2 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_Two)); - EXPECT_CALL(*mock2, Activate()). - Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - EXPECT_CALL(*mock2, Deactivate()). - Times(1); - - // some time later the second entity goes away and comes back - EBUS_EVENT(NetBindingSystemBus, UnbindGameEntity, k_fakeEntityId_Two, k_fakeSliceInstanceId); - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_Two; - spawnContext.m_staticEntityId = k_fakeEntityId_Two; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; // both mock entities come from the same slice - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_Two, spawnContext); - } - - // The same entity should be activated for the second time - EXPECT_CALL(*mock2, Activate()). - Times(1); // Note, Google Mock treats each expect_call separately and satisfies them separately. That's why it's 1 here, despite being a second call. - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } - - TEST_F(ExtendedBindingWithSlicesTest, SliceFailedToSpawn) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EBUS_EVENT_ID(m_sliceTicket, SliceInstantiationResultBus, OnSliceInstantiationFailed, k_fakeAssetId); - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - - EXPECT_TRUE(m_componentApplication->FindEntity(k_fakeEntityId_One) == nullptr); - } - - TEST_F(ExtendedBindingWithSlicesTest, SliceSpawned_AfterTimeout) - { - { - NetBindingSliceContext spawnContext; - spawnContext.m_contextSequence = k_fakeContextSeq; - spawnContext.m_sliceAssetId = k_fakeAssetId; - spawnContext.m_runtimeEntityId = k_fakeEntityId_One; - spawnContext.m_staticEntityId = k_fakeEntityId_One; - spawnContext.m_sliceInstanceId = k_fakeSliceInstanceId; - - EBUS_EVENT(NetBindingSystemBus, SpawnEntityFromSlice, k_repId_One, spawnContext); - } - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - EBUS_EVENT(AZ::TickBus, OnTick, k_wayOverSliceTimeout, AZ::ScriptTimePoint()); - - CreateMockSlice(); - - MockEntity* mock1 = static_cast(m_componentApplication->FindEntity(k_fakeEntityId_One)); - EXPECT_CALL(*mock1, Activate()). - Times(1); - - EBUS_EVENT(AZ::TickBus, OnTick, k_smallStep, AZ::ScriptTimePoint()); - } -} diff --git a/Code/Framework/Tests/NetworkContext.cpp b/Code/Framework/Tests/NetworkContext.cpp deleted file mode 100644 index 5af9ca70d8..0000000000 --- a/Code/Framework/Tests/NetworkContext.cpp +++ /dev/null @@ -1,801 +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 -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace UnitTest -{ - using namespace AZ; - using namespace AzFramework; - - class TestComponentExternalChunk - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponentExternalChunk, "{73BB3B15-7C4D-4BD5-9568-F3B2DCBC7725}", AZ::Component); - - static void Reflect(ReflectContext* context); - - void Init() override - { - NetBindable::NetInit(); - } - - void Activate() override {} - void Deactivate() override {} - - bool SetPos(float x, float y, const RpcContext&) - { - m_x = x; - m_y = y; - return true; - } - - void OnFloatChanged(const float&, const TimeContext&) - { - m_floatChanged = true; - } - - bool m_floatChanged = false; - private: - float m_x = 0, m_y = 0; - }; - - class TestComponentReplicaChunk - : public ReplicaChunkBase - , public ReplicaChunkInterface - { - public: - GM_CLASS_ALLOCATOR(TestComponentReplicaChunk); - static const char* GetChunkName() { return "TestComponentReplicaChunk"; } - bool IsReplicaMigratable() override { return true; } - - public: - TestComponentReplicaChunk() - : m_int("m_int", 42) - , m_float("m_float", 96.4f) - , SetInt("SetInt") - , SetPos("SetPos") - { - } - - bool SetIntImpl(int newValue, const RpcContext&) - { - m_int.Set(newValue); - return true; - } - - DataSet m_int; - DataSet::BindInterface m_float; - GridMate::Rpc > >::BindInterface SetInt; - GridMate::Rpc, GridMate::RpcArg >::BindInterface SetPos; - }; - - void TestComponentExternalChunk::Reflect(ReflectContext* context) - { - NetworkContext* netContext = azrtti_cast(context); - if (netContext) - { - netContext->Class() - ->Chunk() - ->Field("m_int", &TestComponentReplicaChunk::m_int) - ->Field("m_float", &TestComponentReplicaChunk::m_float) - ->RPC("SetInt", &TestComponentReplicaChunk::SetInt) - ->RPC("SetPos", &TestComponentReplicaChunk::SetPos); - } - } - - class TestComponentAutoChunk - : public AZ::Component - , public NetBindable - { - public: - enum TestEnum - { - TEST_Value0 = 0, - TEST_Value1 = 1, - TEST_Value255 = 255 - }; - - AZ_COMPONENT(TestComponentAutoChunk, "{003FD1BC-8456-43D5-9879-1B3804327A4F}", AZ::Component); - - static void Reflect(ReflectContext* context) - { - NetworkContext* netContext = azrtti_cast(context); - if (netContext) - { - netContext->Class() - ->Field("m_int", &TestComponentAutoChunk::m_int) - ->Field("m_float", &TestComponentAutoChunk::m_float) - ->Field("m_enum", &TestComponentAutoChunk::m_enum) - ->RPC("SetInt", &TestComponentAutoChunk::SetInt) - ->CtorData("CtorInt", &TestComponentAutoChunk::GetCtorInt, &TestComponentAutoChunk::SetCtorInt) - ->CtorData("CtorVec", &TestComponentAutoChunk::GetCtorVec, &TestComponentAutoChunk::SetCtorVec); - } - SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->Version(1) - ->Field("m_int", &TestComponentAutoChunk::m_int) - ->Field("m_float", &TestComponentAutoChunk::m_float) - ->Field("m_enum", &TestComponentAutoChunk::m_enum) - ->Field("ctorInt", &TestComponentAutoChunk::m_ctorInt) - ->Field("ctorVec", &TestComponentAutoChunk::m_ctorVec); - } - } - - void Init() override - { - NetBindable::NetInit(); - } - - void Activate() override {} - void Deactivate() override {} - - void SetNetworkBinding(ReplicaChunkPtr chunk) override {} - void UnbindFromNetwork() override {} - - bool SetIntImpl(int val, const RpcContext&) - { - m_int = val; - return true; - } - - void OnFloatChanged(const float&, const TimeContext&) - { - } - - int GetCtorInt() const { return m_ctorInt; } - void SetCtorInt(const int& ctorInt) { m_ctorInt = ctorInt; } - - AZStd::vector& GetCtorVec() { return m_ctorVec; } - void SetCtorVec(const AZStd::vector& vec) { m_ctorVec = vec; } - - int m_ctorInt; - AZStd::vector m_ctorVec; - Field m_int; - BoundField m_float; - Field > m_enum; - Rpc::Binder SetInt; - }; - - class NetContextReflectionTest - : public AllocatorsTestFixture - { - public: - void SetUp() override - { - AllocatorsTestFixture::SetUp(); - - AZ::AllocatorInstance::Create(); - } - - void TearDown() override - { - AZ::AllocatorInstance::Destroy(); - - AllocatorsTestFixture::TearDown(); - } - - void run() - { - AzFramework::Application app; - AzFramework::Application::Descriptor appDesc; - appDesc.m_recordingMode = Debug::AllocationRecords::RECORD_NO_RECORDS; - appDesc.m_allocationRecords = false; - appDesc.m_enableDrilling = false; - - app.Start(appDesc); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - AZ::ComponentDescriptor* descTestComponentExternalChunk = TestComponentExternalChunk::CreateDescriptor(); - app.RegisterComponentDescriptor(descTestComponentExternalChunk); - - AZ::ComponentDescriptor* descTestComponentAutoChunk = TestComponentAutoChunk::CreateDescriptor(); - app.RegisterComponentDescriptor(descTestComponentAutoChunk); - - AZ::Entity* testEntity = aznew AZ::Entity("TestEntity"); - testEntity->Init(); - testEntity->CreateComponent(); - testEntity->CreateComponent(); - testEntity->Activate(); - - // test field binding/auto reflection/creation - { - TestComponentAutoChunk* testComponent = testEntity->FindComponent(); - AZ_TEST_ASSERT(testComponent); - - testComponent->SetInt(2048); // should happen locally - AZ_TEST_ASSERT(testComponent->m_int == 2048); - - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - GridMate::ReplicaChunkDescriptor* desc = chunk->GetDescriptor(); - AZ_TEST_ASSERT(desc); - - testComponent->m_ctorInt = 8192; - for (int n = 0; n < 16; ++n) - { - testComponent->m_ctorVec.push_back(n); - } - - GridMate::WriteBufferDynamic wb(GridMate::EndianType::IgnoreEndian); - desc->MarshalCtorData(chunk.get(), wb); - - { - // Create a chunk from the recorded ctor data, ensure that it stores - // the ctor data in preparation for copying it to the instance - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - ReplicaChunkPtr chunk2 = desc->CreateFromStream(ctx); - AZ_TEST_ASSERT(chunk2); // ensure a new chunk was created - ReflectedReplicaChunkBase* refChunk = static_cast(chunk2.get()); - AZ_TEST_ASSERT(refChunk->m_ctorBuffer.Size() == sizeof(int) + sizeof(AZ::u16) + (sizeof(int) * testComponent->m_ctorVec.size())); - } - - { - // discard a ctor data stream and ensure that the stream is emptied - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - desc->DiscardCtorStream(ctx); - AZ_TEST_ASSERT(rb.IsEmptyIgnoreTrailingBits()); // should have discarded the whole stream - } - - { - // Make another chunk and bind it to a new component and make sure the ctor data matches - AZ::Entity* testEntity2 = aznew AZ::Entity("TestEntity2"); - testEntity2->Init(); - testEntity2->CreateComponent(); - testEntity2->Activate(); - - GridMate::TimeContext tc; - GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = true; - ctx.m_iBuf = &rb; - ReplicaChunkPtr chunk2 = desc->CreateFromStream(ctx); - - TestComponentAutoChunk* testComponent2 = testEntity2->FindComponent(); - netContext->Bind(testComponent2, chunk2, NetworkContextBindMode::NonAuthoritative); - // Ensure values match after ctor data is applied - AZ_TEST_ASSERT(testComponent2->m_ctorInt == testComponent->m_ctorInt); - AZ_TEST_ASSERT(testComponent2->m_ctorVec == testComponent->m_ctorVec); - } - - testComponent->SetInt(4096); - AZ_TEST_ASSERT(testComponent->m_int == 4096); - - testComponent->m_int = 42; // now it should change - AZ_TEST_ASSERT(testComponent->m_int == 42); - testComponent->m_enum = TestComponentAutoChunk::TEST_Value1; - - chunk.reset(); // should cause netContext->DestroyReplicaChunk() - } - - // test chunk binding/creation - { - TestComponentExternalChunk* testComponent = testEntity->FindComponent(); - AZ_TEST_ASSERT(testComponent); - - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - TestComponentReplicaChunk* testChunk = static_cast(chunk.get()); - - // for now, this will throw a warning, but will at least attempt the dispatch - testChunk->SetPos(42.0f, 96.0f); - - AZ_TEST_ASSERT(testComponent->m_floatChanged == false); - testChunk->m_float.Set(1024.0f); - // I would like to test that the notify fired, but without a Replica, cant :( - - testComponent->UnbindFromNetwork(); - chunk.reset(); ///// CRASHES FROM HERE - } - - // test serialization of NetBindable::Fields - { - TestComponentAutoChunk* testComponent = testEntity->FindComponent(); - AZStd::vector buffer; - AZ::IO::ByteContainerStream > saveStream(&buffer); - bool saved = AZ::Utils::SaveObjectToStream(saveStream, AZ::DataStream::ST_XML, testComponent); - AZ_TEST_ASSERT(saved); - AZ::IO::ByteContainerStream > loadStream(&buffer); - TestComponentAutoChunk* testCopy = AZ::Utils::LoadObjectFromStream(loadStream); - AZ_TEST_ASSERT(testCopy); - delete testCopy; - } - - testEntity->Deactivate(); - delete testEntity; - - descTestComponentExternalChunk->ReleaseDescriptor(); - descTestComponentAutoChunk->ReleaseDescriptor(); - - app.Stop(); - } - }; - - TEST_F(NetContextReflectionTest, Test) - { - run(); - } - - template - class NetContextFixture - : public ::testing::Test - { - public: - NetContextFixture() = default; - ~NetContextFixture() = default; - - void SetUp() override - { - AZ::AllocatorInstance::Create(); - - m_app = AZStd::make_unique(); - m_app->Start(AzFramework::Application::Descriptor()); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - m_descTestComponentAutoChunk = ComponentType::CreateDescriptor(); - m_app->RegisterComponentDescriptor(m_descTestComponentAutoChunk); - - m_entity = AZStd::make_unique("TestEntity"); - m_entity->Init(); - m_entity->CreateComponent(); - m_entity->Activate(); - } - - void TearDown() override - { - m_descTestComponentAutoChunk->ReleaseDescriptor(); - - m_entity->Deactivate(); - m_entity.reset(); - - m_app->Stop(); - m_app.reset(); - - AZ::AllocatorInstance::Destroy(); - } - - void RunTest() - { - const ComponentType* testComponent = m_entity->FindComponent(); - AZStd::vector buffer; - AZ::IO::ByteContainerStream > saveStream(&buffer); - const bool saved = AZ::Utils::SaveObjectToStream(saveStream, AZ::DataStream::ST_XML, testComponent); - AZ_TEST_ASSERT(saved); - AZ::IO::ByteContainerStream > loadStream(&buffer); - const AZStd::unique_ptr testCopy(AZ::Utils::LoadObjectFromStream(loadStream)); - AZ_TEST_ASSERT(testCopy); - } - - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_entity; - AZ::ComponentDescriptor* m_descTestComponentAutoChunk = nullptr; - }; - - class TestComponent_EmptyNetContext - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_EmptyNetContext, "{B1E2E2DD-DA70-4D59-A185-AF9A5CCF1574}", AZ::Component, NetBindable); - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class(); - } - } - - void Activate() override {} - void Deactivate() override {} - }; - - using NetContextEmpty = NetContextFixture; - TEST_F(NetContextEmpty, SerializationTests) - { - RunTest(); - } - - template - class TestComponent_OneField - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneField, "{A7BCDBEF-3D4F-4D04-A6FA-DF48D4B66ABE}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneField; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &TestComponent_OneField::m_field) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &TestComponent_OneField::m_field); - } - } - - void Activate() override {} - void Deactivate() override {} - - Field m_field; - }; - - TYPED_TEST_CASE_P(NetContextFixture); - - TYPED_TEST_P(NetContextFixture, SerializationTests) - { - this->RunTest(); - } - - REGISTER_TYPED_TEST_CASE_P(NetContextFixture, SerializationTests); - - /* - * Testing the basic common types. - */ - using CommonTypes = ::testing::Types< - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField - >; - - INSTANTIATE_TYPED_TEST_CASE_P(NetContextCommonSerialization, NetContextFixture, CommonTypes); - - /* - * And some less common types. - */ - using LessCommonTypes = ::testing::Types< - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField, - TestComponent_OneField>, - TestComponent_OneField - >; - - INSTANTIATE_TYPED_TEST_CASE_P(NetContextLessCommonSerialization, NetContextFixture, LessCommonTypes); - - /* - * Next up are marshal and unmarshal tests. - */ - - template - class NetContextMarshalFixture - : public UnitTest::AllocatorsTestFixture - { - public: - NetContextMarshalFixture() = default; - ~NetContextMarshalFixture() = default; - - void SetUp() override - { - UnitTest::AllocatorsTestFixture::SetUp(); - - AZ::AllocatorInstance::Create(); - AZ::AllocatorInstance::Create(); - - m_app = AZStd::make_unique(); - m_app->Start(AzFramework::Application::Descriptor()); - - // Without this, the user settings component would attempt to save on finalize/shutdown. Since the file is - // shared across the whole engine, if multiple tests are run in parallel, the saving could cause a crash - // in the unit tests. - AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize); - - AzFramework::NetworkContext* netContext = nullptr; - EBUS_EVENT_RESULT(netContext, NetSystemRequestBus, GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - m_descTestComponentAutoChunk = ComponentType::CreateDescriptor(); - m_app->RegisterComponentDescriptor(m_descTestComponentAutoChunk); - - m_entityFrom = AZStd::make_unique("TestEntityFrom"); - m_entityFrom->Init(); - m_componentFrom = m_entityFrom->CreateComponent(); - m_entityFrom->Activate(); - - m_entityTo = AZStd::make_unique("TestEntityTo"); - m_entityTo->Init(); - m_componentTo = m_entityTo->CreateComponent(); - m_entityTo->Activate(); - } - - void MarshalUnMarshal() - { - AzFramework::NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_TEST_ASSERT(netContext); - - ComponentType* testComponent = m_entityFrom->FindComponent(); - AZ_TEST_ASSERT(testComponent); - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - AZ_TEST_ASSERT(chunk); - - m_outReplica = AZStd::make_unique("ReplicaTo"); - { - m_outManager = AZStd::make_unique(); - m_outPeer = AZStd::make_unique(m_outManager.get()); - - GridMate::WriteBufferDynamic wb(GridMate::EndianType::IgnoreEndian); - { - GridMate::TimeContext tc; - const GridMate::ReplicaContext rc(nullptr, tc); - GridMate::MarshalContext mc(GridMate::ReplicaMarshalFlags::FullSync, &wb, nullptr, rc); - mc.m_peer = m_outPeer.get(); - mc.m_rm = m_outManager.get(); - chunk->Debug_PrepareData(wb.GetEndianType(), GridMate::ReplicaMarshalFlags::FullSync); - chunk->Debug_Marshal(mc, 0); - } - - // and now unmarshal into the other entity - { - GridMate::TimeContext tc; - const GridMate::ReplicaContext rc(nullptr, tc); - GridMate::ReadBuffer rb(wb.GetEndianType(), wb.Get(), wb.Size()); - GridMate::UnmarshalContext ctx(rc); - ctx.m_hasCtorData = false; - ctx.m_iBuf = &rb; - ctx.m_peer = m_outPeer.get(); - ctx.m_rm = m_outManager.get(); - m_outReplicaChunk = chunk->GetDescriptor()->CreateFromStream(ctx); - - m_outReplicaChunk->Debug_AttachedToReplica(m_outReplica.get()); - ctx.m_peer->Debug_Add(m_outReplica.get()); - m_outReplicaChunk->Debug_Unmarshal(ctx, 0); - /* - * Note the order: unmarshal first to populate the chunk with data, then apply it to a component. - * The expectation is that the valid will apply to NetBindable::Field without being overwritten. - */ - m_componentTo->SetNetworkBinding(m_outReplicaChunk); - - // the main test body can now test for the equality - } - } - } - - void TearDown() override - { - m_outReplicaChunk.reset(); - m_outManager.reset(); - m_outPeer.reset(); - m_outReplica.release(); // Replica is held by as an intrusive pointer in @m_outPeer and is destroyed there. - - if (m_entityFrom) - { - m_entityFrom->Deactivate(); - m_entityFrom.reset(); - } - - if (m_entityTo) - { - m_entityTo->Deactivate(); - m_entityTo.reset(); - } - - m_descTestComponentAutoChunk->ReleaseDescriptor(); - - m_app->Stop(); - m_app.reset(); - - AZ::AllocatorInstance::Destroy(); - AZ::AllocatorInstance::Destroy(); - - UnitTest::AllocatorsTestFixture::TearDown(); - } - - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_entityFrom; - AZStd::unique_ptr m_entityTo; - - ComponentType* m_componentFrom = nullptr; - ComponentType* m_componentTo = nullptr; - - AZ::ComponentDescriptor* m_descTestComponentAutoChunk = nullptr; - - GridMate::ReplicaChunkPtr m_outReplicaChunk; - AZStd::unique_ptr m_outReplica; - AZStd::unique_ptr m_outManager; - AZStd::unique_ptr m_outPeer; - }; - - using NetContextVector3 = NetContextMarshalFixture>; - TEST_F(NetContextVector3, SerializationTests) - { - const Vector3 value = AZ::Vector3::CreateAxisZ( 1.f ); - - m_componentFrom->m_field = value; - MarshalUnMarshal(); - - AZ_TEST_ASSERT(m_componentTo->m_field.Get() == value); - } - - /* - * Now the same test but with NetBindable::BoundField<> - */ - - template - class TestComponent_OneBoundField - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneBoundField, "{2B283821-41DF-46BB-BE8E-66EF7301B62A}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneBoundField; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &ThisComponentType::m_boundField) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &ThisComponentType::m_boundField); - } - } - - void Activate() override {} - void Deactivate() override {} - - void OnBoundFieldChanged( const FieldType&, const GridMate::TimeContext& ) {} - - BoundField m_boundField; - }; - - using NetContextBoundVector2 = NetContextMarshalFixture>; - TEST_F(NetContextBoundVector2, SerializationTests) - { - const Vector2 value = AZ::Vector2::CreateAxisX( 4.f ); - - m_componentFrom->m_boundField = value; - MarshalUnMarshal(); - - AZ_TEST_ASSERT(m_componentTo->m_boundField.Get() == value); - } - - TEST_F(NetContextBoundVector2, Delete_Authoritative_Entity) - { - using ThisComponentType = TestComponent_OneBoundField; - - AzFramework::NetworkContext* netContext = nullptr; - NetSystemRequestBus::BroadcastResult(netContext, &NetSystemRequestBus::Events::GetNetworkContext); - AZ_TEST_ASSERT(netContext); - ThisComponentType* testComponent = m_entityFrom->FindComponent(); - AZ_TEST_ASSERT(testComponent); - ReplicaChunkPtr chunk = testComponent->GetNetworkBinding(); - - // Testing early deletion of an entity on the server. - m_entityFrom->Deactivate(); - m_entityFrom.reset(); - - // This test passes if it doesn't crash on cleanup. - chunk.reset(); - } - - template - class TestComponent_OneBoundField_ServerCallback - : public AZ::Component - , public NetBindable - { - public: - AZ_COMPONENT(TestComponent_OneBoundField_ServerCallback, "{74F5B232-0544-45CA-B207-9846052ED1AD}", AZ::Component, NetBindable); - - using ThisComponentType = TestComponent_OneBoundField_ServerCallback; - - static void Reflect(ReflectContext* context) - { - if (SerializeContext* serializeContext = azrtti_cast(context)) - { - serializeContext->Class() - ->Field("Field", &ThisComponentType::m_boundField) - ->Version(1); - } - if (NetworkContext* netContext = azrtti_cast(context)) - { - netContext->Class() - ->Field("Field", &ThisComponentType::m_boundField); - } - } - - void Activate() override {} - void Deactivate() override {} - - void OnBoundFieldChanged( const FieldType&, const GridMate::TimeContext& ) - { - ++m_callbacksInvokeCount; - } - - AZ::u8 m_callbacksInvokeCount = 0; - - BoundField m_boundField; - }; - - using NetContextBoundVector2WithCallbackCount = NetContextMarshalFixture>; - TEST_F(NetContextBoundVector2WithCallbackCount, BoundField_Invoke_OnServer_Test) - { - MarshalUnMarshal(); - - m_componentFrom->m_callbacksInvokeCount = 0; // resetting the count - - const Vector2 value = AZ::Vector2::CreateAxisX( 4.f ); - m_componentFrom->m_boundField = value; - - AZ_TEST_ASSERT(m_componentFrom->m_callbacksInvokeCount == 1); - } -} diff --git a/Code/Framework/Tests/NetworkMarshal.cpp b/Code/Framework/Tests/NetworkMarshal.cpp deleted file mode 100644 index e9c8b336f6..0000000000 --- a/Code/Framework/Tests/NetworkMarshal.cpp +++ /dev/null @@ -1,552 +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 "TestTypes.h" - -#include -#include -#include -#include - -#include - -namespace UnitTest -{ - template - class MarshalerTester - : public AllocatorsFixture - { - public: - MarshalerTester() - : m_writeBuffer(GridMate::EndianType::BigEndian) - , m_readBuffer(GridMate::EndianType::BigEndian) - { - } - - void SetUp() override - { - AllocatorsFixture::SetUp(); - m_random.SetSeed(AZStd::chrono::milliseconds().count()); - } - - void PopulateReadBuffer() - { - m_readBuffer = GridMate::ReadBuffer(m_writeBuffer.GetEndianType(), m_writeBuffer.Get(), m_writeBuffer.Size()); - } - - AZ::SimpleLcgRandom m_random; - - GridMate::Marshaler m_marshaler; - GridMate::WriteBufferStatic<> m_writeBuffer; - GridMate::ReadBuffer m_readBuffer; - }; - - // EntityIdMarshalerTest - typedef MarshalerTester EntityIdMarshalerTest; - - TEST_F(EntityIdMarshalerTest, SingleMarshalUnmarshalTest_EquivalentEmptyValue) - { - AZ::EntityId initialId; - m_marshaler.Marshal(m_writeBuffer, initialId); - - PopulateReadBuffer(); - - AZ::EntityId receivedId; - m_marshaler.Unmarshal(receivedId, m_readBuffer); - - EXPECT_EQ(initialId,receivedId); - EXPECT_FALSE(receivedId.IsValid()); - } - - TEST_F(EntityIdMarshalerTest, SingleMarshalUnmarshalTest_EquivalentRandomValue) - { - AZ::EntityId initialId = AZ::EntityId(m_random.GetRandom()); - m_marshaler.Marshal(m_writeBuffer, initialId); - - PopulateReadBuffer(); - - AZ::EntityId receivedId; - m_marshaler.Unmarshal(receivedId, m_readBuffer); - - EXPECT_EQ(initialId,receivedId); - } - - TEST_F(EntityIdMarshalerTest, MultipleMarshalUnmarshalTest_EquivalentEmptyRandomEmptyRandomValueChain) - { - AZ::EntityId sentId1_empty; - AZ::EntityId sentId2_random = AZ::EntityId(m_random.GetRandom()); - AZ::EntityId sentId3_empty; - AZ::EntityId sentId4_random = AZ::EntityId(m_random.GetRandom()); - - m_marshaler.Marshal(m_writeBuffer, sentId1_empty); - m_marshaler.Marshal(m_writeBuffer, sentId2_random); - m_marshaler.Marshal(m_writeBuffer, sentId3_empty); - m_marshaler.Marshal(m_writeBuffer, sentId4_random); - - PopulateReadBuffer(); - - AZ::EntityId receivedId1_empty; - AZ::EntityId receivedId2_random; - AZ::EntityId receivedId3_empty; - AZ::EntityId receivedId4_random; - - m_marshaler.Unmarshal(receivedId1_empty, m_readBuffer); - m_marshaler.Unmarshal(receivedId2_random, m_readBuffer); - m_marshaler.Unmarshal(receivedId3_empty, m_readBuffer); - m_marshaler.Unmarshal(receivedId4_random, m_readBuffer); - - EXPECT_EQ(sentId1_empty, receivedId1_empty); - EXPECT_EQ(sentId2_random, receivedId2_random); - EXPECT_EQ(sentId3_empty, receivedId3_empty); - EXPECT_EQ(sentId4_random, receivedId4_random); - } - - // AZ::DynamicSerializableFieldMarshaler - class FooSerializable - { - public: - AZ_RTTI(FooSerializable, "{A60F0B2B-6085-4FF1-BD17-A0B0143BB03D}"); - AZ_CLASS_ALLOCATOR(FooSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("IntValue", &FooSerializable::m_intValue) - ->Field("FloatValue", &FooSerializable::m_floatValue) - ; - } - - FooSerializable() - : m_intValue(0) - , m_floatValue(0.0f) - { - } - - bool operator==(const FooSerializable& other) const - { - return m_intValue == other.m_intValue && AZ::IsClose(m_floatValue, other.m_floatValue,0.0001f); - } - - AZ::u32 m_intValue; - float m_floatValue; - }; - - class BarSerializable - { - public: - AZ_RTTI(BarSerializable, "{2389C23F-D247-420B-A385-71AB8455CD2E}"); - AZ_CLASS_ALLOCATOR(BarSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("LongValue", &BarSerializable::m_longValue) - ->Field("DoubleValue", &BarSerializable::m_doubleValue) - ; - } - - BarSerializable() - : m_longValue(0) - , m_doubleValue(0.0) - { - } - - bool operator==(const BarSerializable& other) const - { - return m_longValue == other.m_longValue && AZ::IsClose(m_doubleValue,other.m_doubleValue,0.0001); - } - - long m_longValue; - double m_doubleValue; - }; - - class ComplexSerializable - { - public: - AZ_RTTI(ComplexSerializable,"{055CB45C-702C-499F-8221-E9ABB21CF1D4}"); - AZ_CLASS_ALLOCATOR(ComplexSerializable, AZ::SystemAllocator,0); - - static void Reflect(AZ::SerializeContext& serializeContext) - { - serializeContext.Class() - ->Version(1) - ->Field("FooSerializable",&ComplexSerializable::m_fooField) - ->Field("BarSerializable",&ComplexSerializable::m_barField) - ; - } - - bool operator==(const ComplexSerializable& other) const - { - return m_fooField == other.m_fooField && m_barField == other.m_barField; - } - - FooSerializable m_fooField; - BarSerializable m_barField; - }; - - class DynamicSerializableFieldMarshalerTest - : public MarshalerTester - , public AZ::ComponentApplicationBus::Handler - { - public: - DynamicSerializableFieldMarshalerTest() - : MarshalerTester() - { - } - - void SetUp() override - { - MarshalerTester::SetUp(); - - FooSerializable::Reflect(m_serializeContext); - BarSerializable::Reflect(m_serializeContext); - ComplexSerializable::Reflect(m_serializeContext); - - // Create the Marshaler with access to our custom serialize context. - m_marshaler = GridMate::Marshaler(&m_serializeContext); - - AZ::ComponentApplicationBus::Handler::BusConnect(); - } - - void TearDown() override - { - MarshalerTester::TearDown(); - - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - } - - FooSerializable* GenerateFooSerializable() - { - FooSerializable* field = new FooSerializable(); - - RandomizeFooSerializable((*field)); - - return field; - } - - void RandomizeFooSerializable(FooSerializable& serializable) - { - serializable.m_intValue = m_random.GetRandom(); - serializable.m_floatValue = m_random.GetRandomFloat(); - } - - BarSerializable* GenerateBarSerializable() - { - BarSerializable* field = new BarSerializable(); - - return field; - } - - void RandomizeBarSerializable(BarSerializable& serializable) - { - serializable.m_longValue = static_cast(m_random.GetRandom()); - serializable.m_doubleValue = static_cast(m_random.GetRandomFloat()); - } - - ComplexSerializable* GenerateComplexSerializable() - { - ComplexSerializable* complexField = new ComplexSerializable(); - - RandomizeFooSerializable(complexField->m_fooField); - RandomizeBarSerializable(complexField->m_barField); - - return complexField; - } - - // Used Component Application Methods - AZ::SerializeContext* GetSerializeContext() { return &m_serializeContext; } - - // Unused ComponentApplication methods - void RegisterComponentDescriptor(const AZ::ComponentDescriptor* descriptor) override { (void)descriptor; AZ_Assert(false,"Unsupported method in Unit Test"); } - void UnregisterComponentDescriptor(const AZ::ComponentDescriptor* descriptor) override { (void)descriptor; AZ_Assert(false,"Unsupported method in Unit Test"); } - - AZ::ComponentApplication* GetApplication() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - bool AddEntity(AZ::Entity* entity) override { (void)entity; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - bool RemoveEntity(AZ::Entity* entity) override { (void)entity; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - bool DeleteEntity(const AZ::EntityId& id) override { (void)id; AZ_Assert(false,"Unsupported method in Unit Test"); return false; } - AZ::Entity* FindEntity(const AZ::EntityId& id) override { (void)id; AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - void EnumerateEntities(const EntityCallback& callback) override { (void)callback; AZ_Assert(false,"Unsupported method in Unit Test"); } - AZ::BehaviorContext* GetBehaviorContext() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - const char* GetAppRoot() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - const char* GetExecutableFolder() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - AZ::Debug::DrillerManager* GetDrillerManager() override { AZ_Assert(false,"Unsupported method in Unit Test"); return nullptr; } - void ReloadModule(const char* moduleFullPath) override { (void)moduleFullPath; AZ_Assert(false,"Unsupported method in Unit Test"); } - - AZ::SerializeContext m_serializeContext; - }; - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentEmptyValue) - { - AZ::DynamicSerializableField sentField; - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentFooValue) - { - AZ::DynamicSerializableField sentField; - - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField.Set(fooSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentBarValue) - { - AZ::DynamicSerializableField sentField; - - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField.Set(barSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, SingleMarshalUnmarshalTest_EquivalentComplexValue) - { - AZ::DynamicSerializableField sentField; - - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField; - m_marshaler.Unmarshal(receivedField,m_readBuffer); - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_EmptyEmptyChainEquivalentValue) - { - AZ::DynamicSerializableField sentField1; - AZ::DynamicSerializableField sentField2; - - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, sentField2); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedField2; - - m_marshaler.Unmarshal(receivedField1,m_readBuffer); - m_marshaler.Unmarshal(receivedField2,m_readBuffer); - - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - receivedField1.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_FooBarComplexChainEquivalentValue) - { - AZ::DynamicSerializableField sentField1; - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField1.Set(fooSerializable); - - AZ::DynamicSerializableField sentField2; - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField2.Set(barSerializable); - - AZ::DynamicSerializableField sentField3; - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField3.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, sentField2); - m_marshaler.Marshal(m_writeBuffer, sentField3); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedField2; - AZ::DynamicSerializableField receivedField3; - - m_marshaler.Unmarshal(receivedField1, m_readBuffer); - m_marshaler.Unmarshal(receivedField2, m_readBuffer); - m_marshaler.Unmarshal(receivedField3, m_readBuffer); - - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - EXPECT_TRUE(sentField3.IsEqualTo(receivedField3, &m_serializeContext)); - - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - sentField3.DestroyData(&m_serializeContext); - - receivedField1.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - receivedField3.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_EmptyFooEmptyBarEmptyComplexChainEquivalentValue) - { - AZ::DynamicSerializableField emptyField; - - AZ::DynamicSerializableField sentField1; - FooSerializable* fooSerializable = GenerateFooSerializable(); - sentField1.Set(fooSerializable); - - AZ::DynamicSerializableField sentField2; - BarSerializable* barSerializable = GenerateBarSerializable(); - sentField2.Set(barSerializable); - - AZ::DynamicSerializableField sentField3; - ComplexSerializable* complexSerializable = GenerateComplexSerializable(); - sentField3.Set(complexSerializable); - - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField1); - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField2); - m_marshaler.Marshal(m_writeBuffer, emptyField); - m_marshaler.Marshal(m_writeBuffer, sentField3); - m_marshaler.Marshal(m_writeBuffer, emptyField); - - PopulateReadBuffer(); - - AZ::DynamicSerializableField receivedEmptyField1; - AZ::DynamicSerializableField receivedField1; - AZ::DynamicSerializableField receivedEmptyField2; - AZ::DynamicSerializableField receivedField2; - AZ::DynamicSerializableField receivedEmptyField3; - AZ::DynamicSerializableField receivedField3; - AZ::DynamicSerializableField receivedEmptyField4; - - m_marshaler.Unmarshal(receivedEmptyField1, m_readBuffer); - m_marshaler.Unmarshal(receivedField1, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField2, m_readBuffer); - m_marshaler.Unmarshal(receivedField2, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField3, m_readBuffer); - m_marshaler.Unmarshal(receivedField3, m_readBuffer); - m_marshaler.Unmarshal(receivedEmptyField4, m_readBuffer); - - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField1, &m_serializeContext)); - EXPECT_TRUE(sentField1.IsEqualTo(receivedField1, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField2, &m_serializeContext)); - EXPECT_TRUE(sentField2.IsEqualTo(receivedField2, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField3, &m_serializeContext)); - EXPECT_TRUE(sentField3.IsEqualTo(receivedField3, &m_serializeContext)); - EXPECT_TRUE(emptyField.IsEqualTo(receivedEmptyField4, &m_serializeContext)); - - emptyField.DestroyData(&m_serializeContext); - sentField1.DestroyData(&m_serializeContext); - sentField2.DestroyData(&m_serializeContext); - sentField3.DestroyData(&m_serializeContext); - - receivedEmptyField1.DestroyData(&m_serializeContext); - receivedField1.DestroyData(&m_serializeContext); - receivedEmptyField2.DestroyData(&m_serializeContext); - receivedField2.DestroyData(&m_serializeContext); - receivedEmptyField3.DestroyData(&m_serializeContext); - receivedField3.DestroyData(&m_serializeContext); - receivedEmptyField4.DestroyData(&m_serializeContext); - } - - TEST_F(DynamicSerializableFieldMarshalerTest, MultipleMarshalUnmarshalTest_RandomChainEquivalentValue) - { - // Need to watch out for the size of the WriteBuffer. It's about ~2048 bytes, at worst case here, I'll write ~100 Bytes to the field per test object) - // So I need to keep this ~20 elements. - int numValues = 5 + m_random.GetRandom()%10; - AZStd::vector< AZ::DynamicSerializableField > sentValues; - AZStd::vector< AZ::DynamicSerializableField > receivedValues; - - sentValues.resize(numValues); - receivedValues.resize(numValues); - - for (auto& currentField : sentValues) - { - int value = m_random.GetRandom() % 4; - switch (value) - { - case 0: - { - currentField.Set(GenerateFooSerializable()); - } - break; - case 1: - { - currentField.Set(GenerateBarSerializable()); - } - break; - case 2: - { - currentField.Set(GenerateComplexSerializable()); - } - break; - case 3: - default: - // Empty field - break; - } - } - - for (auto& currentField : sentValues) - { - m_marshaler.Marshal(m_writeBuffer,currentField); - } - - PopulateReadBuffer(); - - for (auto& currentField : receivedValues) - { - m_marshaler.Unmarshal(currentField,m_readBuffer); - } - - for (unsigned int i=0; i < sentValues.size(); ++i) - { - AZ::DynamicSerializableField& sentField = sentValues[i]; - AZ::DynamicSerializableField& receivedField = receivedValues[i]; - - EXPECT_TRUE(sentField.IsEqualTo(receivedField, &m_serializeContext)); - - sentField.DestroyData(&m_serializeContext); - receivedField.DestroyData(&m_serializeContext); - } - } -} diff --git a/Code/Framework/Tests/Script/ScriptComponentTests.cpp b/Code/Framework/Tests/Script/ScriptComponentTests.cpp index a463192dd0..54c0d1dfa3 100644 --- a/Code/Framework/Tests/Script/ScriptComponentTests.cpp +++ b/Code/Framework/Tests/Script/ScriptComponentTests.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include "EntityTestbed.h" @@ -63,8 +62,6 @@ namespace UnitTest EBUS_EVENT_RESULT(m_behaviorContext, AZ::ComponentApplicationBus, GetBehaviorContext); EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - NetBindable::Reflect(m_serializeContext); - AzToolsFramework::Components::ScriptEditorComponent::CreateDescriptor(); // descriptor is deleted by app AzToolsFramework::Components::ScriptEditorComponent::Reflect(m_serializeContext); @@ -228,63 +225,4 @@ namespace UnitTest EXPECT_NE(scriptComponent->GetScriptProperty("myNum"), nullptr); } - - TEST_F(ScriptComponentTest, UpdateNetSynchedProperty) - { - // Make sure altering a netsynched property in script only affects the single entity instance - const AZStd::string script = "local test = {\ - Properties = {\ - myNetSynchedNum = { default = 41, netSynched ={} },\ - doUpdate = { default = false },\ - },\ - }\ - function test:OnActivate()\ - self.tickBusHandler = TickBus.Connect(self, self.entityId)\ - end\ - function test:OnDeactivate()\ - self.tickBusHandler:Disconnect()\ - end\ - function test:OnTick(deltaTime, timePoint)\ - if self.Properties.doUpdate then\ - self.Properties.myNetSynchedNum = self.Properties.myNetSynchedNum+1\ - end\ - end\ - return test"; - - - const Data::Asset scriptAsset = CreateAndLoadScriptAsset(script); - Entity entity1, entity2; - ScriptComponent* scriptComponentInstance1 = BuildGameEntity(scriptAsset, entity1); - ScriptComponent* scriptComponentInstance2 = BuildGameEntity(scriptAsset, entity2); - - // Change the value of entity1's doUpdate to true. - // This way entity1's myNetSynchedNum should be incremented during OnTick - auto* doUpdateScriptProperty = azrtti_cast(scriptComponentInstance1->GetScriptProperty("doUpdate")); - ASSERT_NE(doUpdateScriptProperty, nullptr); - doUpdateScriptProperty->m_value = true; - - entity1.Init(); - entity2.Init(); - entity1.Activate(); - entity2.Activate(); - - // Tick in order to call OnTick in our lua script. - m_app.Tick(); - m_app.TickSystem(); - - // Ensure Entity1's myNetSynchedNum updated, but not Entity2 - auto* netSynchedProperty1 = scriptComponentInstance1->GetNetworkedScriptProperty("myNetSynchedNum"); - auto* netSynchedProperty2 = scriptComponentInstance2->GetNetworkedScriptProperty("myNetSynchedNum"); - ASSERT_NE(netSynchedProperty1, nullptr); - ASSERT_NE(netSynchedProperty2, nullptr); - - auto* num1 = azrtti_cast(netSynchedProperty1); - auto* num2 = azrtti_cast(netSynchedProperty2); - - ASSERT_NE(num1, nullptr); - ASSERT_NE(num2, nullptr); - - EXPECT_EQ(num1->m_value, 42); - EXPECT_EQ(num2->m_value, 41); - } } // namespace UnitTest diff --git a/Code/Framework/Tests/TransformComponent.cpp b/Code/Framework/Tests/TransformComponent.cpp index de172dc051..c2615f2a30 100644 --- a/Code/Framework/Tests/TransformComponent.cpp +++ b/Code/Framework/Tests/TransformComponent.cpp @@ -955,37 +955,6 @@ namespace UnitTest const char* m_objectStreamBuffer = nullptr; }; - class TransformComponentConvertFromV2 - : public TransformComponentVersionConverter - { - public: - TransformComponentConvertFromV2() - { - m_objectStreamBuffer = - R"DELIMITER( - - - - - - - - - - - - - - -)DELIMITER"; - } - }; - - TEST_F(TransformComponentConvertFromV2, IsStatic_False) - { - EXPECT_FALSE(m_transformInterface->IsStaticTransform()); - } - /////////////////////////////////////////////////////////////////////////// // TransformConfig diff --git a/Code/Framework/Tests/frameworktests_files.cmake b/Code/Framework/Tests/frameworktests_files.cmake index cf02b007b4..07990dc8fa 100644 --- a/Code/Framework/Tests/frameworktests_files.cmake +++ b/Code/Framework/Tests/frameworktests_files.cmake @@ -26,8 +26,6 @@ set(FILES GenAppDescriptors.cpp GenericComponentWrapperTest.cpp InstanceDataHierarchy.cpp - NetBinding.cpp - NetworkContext.cpp OctreePerformanceTests.cpp OctreeTests.cpp Slices.cpp @@ -35,12 +33,8 @@ set(FILES Script/ScriptEntityTests.cpp AssetCatalog.cpp AssetProcessorConnection.cpp - NetBindingSystemImplTest.cpp - NetBindingMocks.h NativeWindow.cpp TransformComponent.cpp - GridMocks.h - InterestManagerComponentTests.cpp SQLiteConnectionTests.cpp ProcessLaunchParseTests.cpp Application.cpp diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp deleted file mode 100644 index 904f500018..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -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 m_param0; - * - * or if using delta compression feature of GridMate: - * - * DeltaCompressedDataSet 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; - - template - using AnimDataSet = AnimDataSetType::BindInterface; - - // 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 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:: - BindInterface m_activeNodes; - GridMate::DataSet:: - BindInterface m_motionNodes; - }; - - void AnimGraphNetSyncComponent::Reflect(AZ::ReflectContext* context) - { - GridMate::ReplicaChunkDescriptorTable& descTable = GridMate::ReplicaChunkDescriptorTable::Get(); - if (!descTable.FindReplicaChunkDescriptor(GridMate::ReplicaChunkClassId(Chunk::GetChunkName()))) - { - descTable.RegisterChunkType(); - } - - AZ::SerializeContext* serializeContext = azrtti_cast(context); - if (serializeContext) - { - serializeContext->Class() - ->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("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 - void AnimGraphNetSyncComponent::OnAnimParameterChanged(const AnimParameter& value, const GridMate::TimeContext&) - { - SetParameterOnClient(value, Index); - } - - template - 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(¶m.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(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphBoolParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - bool beforeValue, - bool afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(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(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphVector3ParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Vector3& beforeValue, - const AZ::Vector3& afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(parameterIndex), afterValue); - } - - void AnimGraphNetSyncComponent::OnAnimGraphRotationParameterChanged(EMotionFX::AnimGraphInstance*, - AZ::u32 parameterIndex, - const AZ::Quaternion& beforeValue, - const AZ::Quaternion& afterValue) - { - AZ_UNUSED(beforeValue); - SetParameterOnServer(static_cast(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 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 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 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(m_chunk.get()); - } - - GridMate::ReplicaChunkPtr AnimGraphNetSyncComponent::GetNetworkBinding() - { - m_chunk = GridMate::CreateReplicaChunk(); - 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 diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h deleted file mode 100644 index b6cfc2c795..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncComponent.h +++ /dev/null @@ -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 -#include -#include -#include -#include - -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 - 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 - 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 diff --git a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h b/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h deleted file mode 100644 index 9194dc1b65..0000000000 --- a/Gems/EMotionFX/Code/Source/Integration/Components/AnimGraphNetSyncTypes.h +++ /dev/null @@ -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 -#include -#include - -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(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& 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 diff --git a/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp b/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp index 4d7db16133..e5561697fd 100644 --- a/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/System/AnimationModule.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -74,8 +73,6 @@ namespace EMotionFX AnimGraphComponent::CreateDescriptor(), SimpleMotionComponent::CreateDescriptor(), SimpleLODComponent::CreateDescriptor(), - - Network::AnimGraphNetSyncComponent::CreateDescriptor(), #if defined(EMOTIONFXANIMATION_EDITOR) // Pipeline components diff --git a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake index 0c7e4ef0e7..88c6525f91 100644 --- a/Gems/EMotionFX/Code/emotionfx_shared_files.cmake +++ b/Gems/EMotionFX/Code/emotionfx_shared_files.cmake @@ -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 diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h index 4374b67e32..a1fb6d5572 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.h @@ -14,6 +14,7 @@ #include #include +#include #include diff --git a/Gems/PhysX/Code/Tests/PhysXTestCommon.h b/Gems/PhysX/Code/Tests/PhysXTestCommon.h index c4d08953eb..d130cccf9f 100644 --- a/Gems/PhysX/Code/Tests/PhysXTestCommon.h +++ b/Gems/PhysX/Code/Tests/PhysXTestCommon.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp index ba1d34fea0..d5745cf3cc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp @@ -19,11 +19,9 @@ #include #include #include -#include #include #include #include -#include #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) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h index ef90155e41..81f46d27b9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h @@ -15,8 +15,6 @@ #include #include -#include - #include #include #include @@ -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 m_runtimeAsset; ExecutionStatePtr m_executionState; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp deleted file mode 100644 index 8d8db1d876..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include - -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 typeMarshaler; - const Data::eType& datumType = property->GetType().GetType(); - typeMarshaler.Marshal(wb, datumType); - - VariableId assetVariableId; - AZStd::unordered_map>& variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap(); - - for (AZStd::pair>& pair : variableIdMap) - { - AZStd::pair& variableIndexPair = pair.second; - - if (variableIndexPair.first->GetDatum() == property) - { - assetVariableId = m_graphVariableNetBindingTable->FindAssetVariableIdByRuntimeVariableId(pair.first); - break; - } - } - - if (!assetVariableId.IsValid()) - { - return; - } - - GridMate::Marshaler uuidMarshaler; - uuidMarshaler.Marshal(wb, assetVariableId.GetDatumId()); - - AZStd::string uuidString = assetVariableId.m_id.ToString(); - - switch (datumType) - { - case Data::eType::AABB: - MarshalType(wb, property); - break; - - case Data::eType::Boolean: - MarshalType(wb, property); - break; - - case Data::eType::Color: - MarshalType(wb, property); - break; - - case Data::eType::CRC: - MarshalType(wb, property); - break; - - case Data::eType::EntityID: - MarshalType(wb, property); - break; - - case Data::eType::Matrix3x3: - MarshalType(wb, property); - break; - - case Data::eType::Matrix4x4: - MarshalType(wb, property); - break; - - case Data::eType::NamedEntityID: - MarshalType(wb, property); - break; - - case Data::eType::Number: - MarshalType(wb, property); - break; - - case Data::eType::OBB: - MarshalType(wb, property); - break; - - case Data::eType::Plane: - MarshalType(wb, property); - break; - - case Data::eType::Quaternion: - MarshalType(wb, property); - break; - - case Data::eType::String: - MarshalType(wb, property); - break; - - case Data::eType::Transform: - MarshalType(wb, property); - break; - - case Data::eType::Vector2: - MarshalType(wb, property); - break; - - case Data::eType::Vector3: - MarshalType(wb, property); - break; - - case Data::eType::Vector4: - MarshalType(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 typeMarshaler; - typeMarshaler.Unmarshal(datumType, rb); - - AZ::Uuid uuid; - GridMate::Marshaler 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::unordered_map>& m_variableIdMap = m_graphVariableNetBindingTable->GetVariableIdMap(); - AZStd::pair& variableIndexPair = m_variableIdMap[runtimeVariableId]; - GraphVariable* graphVariable = variableIndexPair.first; - - switch (datumType) - { - case Data::eType::AABB: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Boolean: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Color: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::CRC: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::EntityID: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Matrix3x3: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Matrix4x4: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::NamedEntityID: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Number: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::OBB: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Plane: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Quaternion: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::String: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Transform: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector2: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector3: - return UnmarshalType(target, rb, graphVariable); - - case Data::eType::Vector4: - return UnmarshalType(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; - } -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h deleted file mode 100644 index 5fd8c3fa0d..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableMarshal.h +++ /dev/null @@ -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 -#include -#include -#include - -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 - void MarshalType(GridMate::WriteBuffer& wb, const Datum* const & property) const - { - GridMate::Marshaler marshaler; - const T* value = property->GetAs(); - marshaler.Marshal(wb, *value); - } - - template - 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 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; - }; -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp deleted file mode 100644 index e30cb95255..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.cpp +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include - -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(); - } - } - - GridMate::ReplicaChunkPtr GraphVariableNetBindingTable::GetNetworkBinding() - { - if (!m_replicaChunk) - { - m_replicaChunk = GridMate::CreateReplicaChunk(); - 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(index)); - } - - void GraphVariableNetBindingTable::OnDatumChanged(GraphVariable& variable) - { - if (m_replicaChunk && m_replicaChunk->IsMaster()) - { - GraphVariableReplicaChunk* graphVarChunk = static_cast(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& pair = iter->second; - DatumDataSet& datumDataSet = graphVarChunk->m_properties[pair.second]; - datumDataSet.GetThrottler().SignalDirty(); - datumDataSet.Set(variable.GetDatum()); - } - } - - void GraphVariableNetBindingTable::SetVariableMappings(const AZStd::unordered_map& assetToRuntimeVariableMap, const AZStd::unordered_map& 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>& GraphVariableNetBindingTable::GetVariableIdMap() - { - return m_variableIdMap; - } - - void GraphVariableNetBindingTable::SetGraphNetBindingTable() - { - GraphVariableReplicaChunk* graphVariableChunk = static_cast(m_replicaChunk.get()); - - for (DatumDataSet& dataSet : graphVariableChunk->m_properties) - { - dataSet.GetMarshaler().SetNetBindingTable(this); - } - } -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h deleted file mode 100644 index d0f945523d..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariableNetBindings.h +++ /dev/null @@ -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 -#include -#include -#include -#include - -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& assetToRuntimeVariableMap, const AZStd::unordered_map& runtimeToAssetVariableMap); - VariableId FindAssetVariableIdByRuntimeVariableId(VariableId runtimeVariableId); - VariableId FindRuntimeVariableIdByAssetVariableId(VariableId assetVariableId); - AZStd::unordered_map>& GetVariableIdMap(); - - private: - void SetGraphNetBindingTable(); - - private: - AZStd::unordered_map m_assetToRuntimeVariableMap; - AZStd::unordered_map 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> m_variableIdMap; - }; - - typedef GridMate::DataSet::BindInterface 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]; - }; -} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 871d8d4c5d..84391021df 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -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