From a56be14677fc82376a3a68ec1e637190a58550d0 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Fri, 13 Aug 2021 17:25:01 -0700 Subject: [PATCH 01/27] JSON saving of SC editor assets Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Assets/ScriptCanvasAssetHandler.cpp | 99 ++++++++----------- .../Serialization/DatumSerializer.cpp | 3 +- 2 files changed, 44 insertions(+), 58 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 55da572939..c355797f27 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -6,29 +6,33 @@ * */ - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include #include #include +#include +#include +#include +#include +#include +#include #include - #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// \todo move out and replace with JsonUtils.h when it can get moved +#include +#include +#include +#include + namespace ScriptCanvasEditor { @@ -75,14 +79,16 @@ namespace ScriptCanvasEditor } } - AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData( const AZ::Data::Asset& asset, AZStd::shared_ptr stream, const AZ::Data::AssetFilterCB& assetLoadFilterCB) { auto* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "This should be an scene slice asset, as this is the only type we process!"); + AZ_Assert(scriptCanvasAsset, "This should be a ScriptCanvasAsset, as this is the only type we process!"); + + // static_assert(false, "load the json here, and only if it failed, conditionally load the block below"); + if (scriptCanvasAsset && m_serializeContext) { stream->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); @@ -91,10 +97,8 @@ namespace ScriptCanvasEditor return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error; } return AZ::Data::AssetHandler::LoadResult::Error; - } - bool ScriptCanvasAssetHandler::SaveAssetData(const AZ::Data::Asset& asset, AZ::IO::GenericStream* stream) { return SaveAssetData(asset.GetAs(), stream); @@ -105,17 +109,24 @@ namespace ScriptCanvasEditor return SaveAssetData(assetData, stream, AZ::DataStream::ST_XML); } - bool ScriptCanvasAssetHandler::SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, AZ::DataStream::StreamType streamType) + bool ScriptCanvasAssetHandler::SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, [[maybe_unused]] AZ::DataStream::StreamType streamType) { + namespace JSR = AZ::JsonSerializationResult; + if (assetData && m_serializeContext) - { - AZStd::vector byteBuffer; - AZ::IO::ByteContainerStream byteStream(&byteBuffer); - AZ::ObjectStream* objStream = AZ::ObjectStream::Create(&byteStream, *m_serializeContext, streamType); - bool scriptCanvasAssetSaved = objStream->WriteClass(&assetData->GetScriptCanvasData()); - objStream->Finalize(); - scriptCanvasAssetSaved = stream->Write(byteBuffer.size(), byteBuffer.data()) == byteBuffer.size() && scriptCanvasAssetSaved; - return scriptCanvasAssetSaved; + { + AZ::JsonSerializerSettings settings; + settings.m_keepDefaults = false; + settings.m_serializeContext = m_serializeContext; + rapidjson::Document document; + + if (AZ::JsonSerialization::Store(document, document.GetAllocator(), assetData->GetScriptCanvasData(), settings).GetProcessing() != JSR::Processing::Halted) + { + // \todo replace with with exact function from JsonUtils.cpp once it is moved to AzToolsFramework + AZ::IO::RapidJSONStreamWriter jsonStreamWriter(stream); + rapidjson::PrettyWriter writer(jsonStreamWriter); + return document.Accept(writer); + } } return false; @@ -126,17 +137,11 @@ namespace ScriptCanvasEditor delete ptr; } - //========================================================================= - // GetSerializeContext - //=========================================================================. AZ::SerializeContext* ScriptCanvasAssetHandler::GetSerializeContext() const { return m_serializeContext; } - //========================================================================= - // SetSerializeContext - //=========================================================================. void ScriptCanvasAssetHandler::SetSerializeContext(AZ::SerializeContext* context) { m_serializeContext = context; @@ -152,17 +157,11 @@ namespace ScriptCanvasEditor } } - //========================================================================= - // GetHandledAssetTypes - //=========================================================================. void ScriptCanvasAssetHandler::GetHandledAssetTypes(AZStd::vector& assetTypes) { assetTypes.push_back(GetAssetType()); } - //========================================================================= - // GetAssetType - //=========================================================================. AZ::Data::AssetType ScriptCanvasAssetHandler::GetAssetType() const { return ScriptCanvasAssetHandler::GetAssetTypeStatic(); @@ -178,38 +177,24 @@ namespace ScriptCanvasEditor return azrtti_typeid(); } - //========================================================================= - // GetAssetTypeExtensions - //=========================================================================. void ScriptCanvasAssetHandler::GetAssetTypeExtensions(AZStd::vector& extensions) { ScriptCanvasAsset::Description description; extensions.push_back(description.GetExtensionImpl()); } - //========================================================================= - // GetComponentTypeId - //=========================================================================. AZ::Uuid ScriptCanvasAssetHandler::GetComponentTypeId() const { return azrtti_typeid(); } - //========================================================================= - // GetGroup - //=========================================================================. const char* ScriptCanvasAssetHandler::GetGroup() const { return ScriptCanvas::AssetDescription::GetGroup(); } - //========================================================================= - // GetBrowserIcon - //=========================================================================. const char* ScriptCanvasAssetHandler::GetBrowserIcon() const { return ScriptCanvas::AssetDescription::GetIconPath(); } - - } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp index 44ca1730a8..003ef05774 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -84,7 +84,8 @@ namespace AZ AZStd::string label; AZ_Assert(azrtti_typeidm_datumLabel)>() == azrtti_typeid() , "m_datumLabel type changed and won't load properly"); - result.Combine(ContinueLoadingFromJsonObjectField + + result.Combine( ContinueLoadingFromJsonObjectField ( &label , azrtti_typeidm_datumLabel)>() , inputValue From 504420483925d67cf380715f14588eebc8492151 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Fri, 13 Aug 2021 21:53:20 -0700 Subject: [PATCH 02/27] Move JsonUtils.h for support of SC serialization Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AtomCore/AtomCore/atomcore_files.cmake | 2 - .../Tests/JsonSerializationUtilsTests.cpp | 2 +- .../Serialization/Json/JsonUtils.cpp | 7 +- .../Serialization/Json/JsonUtils.h | 2 + .../aztoolsframework_files.cmake | 2 + .../BuilderSettings/BuilderSettingManager.cpp | 2 +- .../Code/Source/Editor/AtomShaderConfig.cpp | 2 +- .../Code/Source/Editor/AzslCompiler.cpp | 2 +- .../Editor/CommonFiles/GlobalBuildOptions.cpp | 2 +- .../Editor/CommonFiles/Preprocessor.cpp | 2 +- .../Editor/PrecompiledShaderBuilder.cpp | 2 +- .../Code/Source/Editor/ShaderAssetBuilder.cpp | 2 +- .../Source/Editor/ShaderBuilderUtility.cpp | 2 +- .../Editor/ShaderVariantAssetBuilder.cpp | 2 +- Gems/Atom/Feature/Common/Code/CMakeLists.txt | 4 + .../Source/FrameCaptureSystemComponent.cpp | 2 +- .../ProfilingCaptureSystemComponent.cpp | 2 +- Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp | 2 +- Gems/Atom/RPI/Code/CMakeLists.txt | 3 + .../Include/Atom/RPI.Edit/Common/JsonUtils.h | 2 +- .../RPI.Builders/Common/AnyAssetBuilder.cpp | 2 +- .../RPI.Builders/Material/MaterialBuilder.cpp | 2 +- .../Source/RPI.Builders/Pass/PassBuilder.cpp | 2 +- .../ResourcePool/ResourcePoolBuilder.cpp | 2 +- .../MaterialFunctorSourceDataSerializer.cpp | 2 +- .../MaterialPropertyValueSerializer.cpp | 2 +- .../RPI.Edit/Material/MaterialSourceData.cpp | 2 +- .../Material/MaterialSourceDataSerializer.cpp | 2 +- .../RPI.Edit/Material/MaterialUtils.cpp | 2 +- .../RPI.Public/Pass/AttachmentReadback.cpp | 2 +- .../Source/RPI.Public/Pass/PassSystem.cpp | 2 +- .../Shader/Metrics/ShaderMetrics.cpp | 2 +- .../Shader/Metrics/ShaderMetricsSystem.cpp | 2 +- .../Tests.Builders/AnyAssetBuilderTest.cpp | 2 +- .../Code/Tests.Builders/PassBuilderTest.cpp | 2 +- .../ResourcePoolBuilderTest.cpp | 2 +- .../RPI/Code/Tests/Common/JsonTestUtils.h | 2 +- .../Tests/Material/MaterialFunctorTests.cpp | 2 +- .../MaterialPropertySerializerTests.cpp | 2 +- .../Material/MaterialTypeSourceDataTests.cpp | 2 +- .../Viewport/MaterialViewportComponent.cpp | 2 +- ...ssetCollectionAsyncLoaderTestComponent.cpp | 2 +- .../Assets/ScriptCanvasAssetHandler.cpp | 79 +++++++++++-------- 43 files changed, 96 insertions(+), 75 deletions(-) rename Code/Framework/{AtomCore/AtomCore => AzToolsFramework/AzToolsFramework}/Serialization/Json/JsonUtils.cpp (99%) rename Code/Framework/{AtomCore/AtomCore => AzToolsFramework/AzToolsFramework}/Serialization/Json/JsonUtils.h (99%) diff --git a/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake b/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake index bcfbfb2764..c90263468f 100644 --- a/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake +++ b/Code/Framework/AtomCore/AtomCore/atomcore_files.cmake @@ -13,8 +13,6 @@ set(FILES Instance/InstanceData.h Instance/InstanceData.cpp Instance/InstanceDatabase.h - Serialization/Json/JsonUtils.h - Serialization/Json/JsonUtils.cpp std/containers/array_view.h std/containers/fixed_vector_set.h std/containers/lru_cache.h diff --git a/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp b/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp index 77bcb0c08d..79e0bf86ee 100644 --- a/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp +++ b/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp @@ -13,7 +13,7 @@ #include -#include +#include namespace UnitTest { diff --git a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp similarity index 99% rename from Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp rename to Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp index 1d3a9674a0..89cf667958 100644 --- a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp @@ -6,7 +6,6 @@ * */ -#include #include #include #include @@ -23,6 +22,8 @@ #include #include +#include "JsonUtils.h" + namespace AZ { namespace JsonSerializationUtils @@ -343,9 +344,9 @@ namespace AZ { return AZ::Failure(deserializeErrors); } + return AZ::Success(); - } - + } AZ::Outcome LoadAnyObjectFromStream(IO::GenericStream& stream, const JsonDeserializerSettings* settings) { diff --git a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.h similarity index 99% rename from Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.h rename to Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.h index c7777feec0..62020d81d0 100644 --- a/Code/Framework/AtomCore/AtomCore/Serialization/Json/JsonUtils.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.h @@ -15,6 +15,8 @@ #include #include +// hello? + namespace AZ { namespace IO diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 14c5f34f90..0c49da841f 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -205,6 +205,8 @@ set(FILES PropertyTreeEditor/PropertyTreeEditorComponent.h Render/EditorIntersectorComponent.cpp Render/EditorIntersectorComponent.h + Serialization/Json/JsonUtils.h + Serialization/Json/JsonUtils.cpp Slice/SliceDataFlagsCommand.h Slice/SliceDataFlagsCommand.cpp Slice/SliceUtilities.h diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp index 46b684493b..764a19d549 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include namespace ImageProcessingAtom { diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp index fcb486ec32..b299108518 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include namespace AZ diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp index cc42fac422..397d47ef21 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include // [GFX TODO] Remove when [ATOM-15472] diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp index 66b4d2e833..1b3b7c595d 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp index 945f9734ca..adec465a9f 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp index 5d712a4a8a..6d876c0ad4 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp index b1a3de2794..d3fa043fa2 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp index d7c3de48c0..df0d9b10a2 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 1da4623774..8bbae7502b 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Feature/Common/Code/CMakeLists.txt b/Gems/Atom/Feature/Common/Code/CMakeLists.txt index 8ed02f2c2f..8a9fe3b07c 100644 --- a/Gems/Atom/Feature/Common/Code/CMakeLists.txt +++ b/Gems/Atom/Feature/Common/Code/CMakeLists.txt @@ -34,6 +34,7 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework PUBLIC Gem::Atom_RPI.Public Gem::Atom_Utils.Static @@ -62,6 +63,7 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework PUBLIC Gem::Atom_RPI.Public Gem::Atom_Utils.Static @@ -85,6 +87,7 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework Gem::Atom_Feature_Common.Static Gem::Atom_Feature_Common.Public 3rdParty::lux_core @@ -161,6 +164,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) BUILD_DEPENDENCIES PRIVATE AZ::AzFramework + AZ::AzToolsFramework AZ::AzTest Gem::Atom_Feature_Common.Static Gem::Atom_Feature_Common.Public diff --git a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp index 4b1a6ec7f6..4eb5ab0a76 100644 --- a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp index add6d0e098..da194d4d4e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp index 8c64f1611f..f0fbf40a14 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/CMakeLists.txt b/Gems/Atom/RPI/Code/CMakeLists.txt index 521178be20..54e74b756b 100644 --- a/Gems/Atom/RPI/Code/CMakeLists.txt +++ b/Gems/Atom/RPI/Code/CMakeLists.txt @@ -40,6 +40,7 @@ ly_add_target( AZ::AtomCore AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework PUBLIC Gem::Atom_RHI.Public ) @@ -62,6 +63,7 @@ ly_add_target( AZ::AtomCore AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework Gem::Atom_RPI.Public Gem::Atom_RHI.Public Gem::Atom_RHI.Reflect @@ -107,6 +109,7 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AtomCore AZ::AzCore AZ::AzFramework + AZ::AzToolsFramework Gem::Atom_RPI.Public Gem::Atom_RHI.Public ) diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h index 3e3fbec8fe..22baf5776a 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp index 4074568fbe..031b928543 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index d07f073d4f..70230cfffb 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp index 652130dea2..2949125fc1 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp @@ -11,7 +11,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp index 1dcab2679f..24a105a4f4 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp @@ -16,7 +16,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp index 3ba115f3e6..52b56f254a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp index 708644ae20..3c702b84a0 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index 1fee57759c..8d799fe440 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp index e65c65a39a..466fd79dd8 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index 67c143c074..7fb9d3d70f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp index 29a17dc9a8..15fadd894b 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp index d73521763f..6d470427b5 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp index 5df21f3964..7e5c268112 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp @@ -6,7 +6,7 @@ * */ #include -#include +#include namespace AZ { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp index d0d76e62de..47c8dedd8d 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp index fcec484fa9..33b4bc61fe 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp index ad1df41824..993bd8ded2 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp index d6107cda9e..2623cade02 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h b/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h index 2c38090b43..3b66565f99 100644 --- a/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h +++ b/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include namespace UnitTest diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp index cf64fd12f3..9b82f501d2 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp @@ -19,7 +19,7 @@ #include #include -//#include +//#include namespace UnitTest { using namespace AZ; diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp index 759842cf96..fdd8edf5e5 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp index 44b59059ba..85beba6721 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index d957ea327c..ec2f200ff2 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp index b51e3b0e29..f0a8e35699 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp @@ -13,7 +13,7 @@ #include -#include +#include // Included so we can deduce the asset type from asset paths. #include diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index c355797f27..ee78a71772 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -27,13 +28,6 @@ #include #include -// \todo move out and replace with JsonUtils.h when it can get moved -#include -#include -#include -#include - - namespace ScriptCanvasEditor { ScriptCanvasAssetHandler::ScriptCanvasAssetHandler(AZ::SerializeContext* context) @@ -79,23 +73,45 @@ namespace ScriptCanvasEditor } } - AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData( - const AZ::Data::Asset& asset, - AZStd::shared_ptr stream, - const AZ::Data::AssetFilterCB& assetLoadFilterCB) + AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData + ( const AZ::Data::Asset& assetTarget + , AZStd::shared_ptr streamSource + , const AZ::Data::AssetFilterCB& assetLoadFilterCB) { - auto* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "This should be a ScriptCanvasAsset, as this is the only type we process!"); + namespace JSRU = AZ::JsonSerializationUtils; + using namespace ScriptCanvas; - // static_assert(false, "load the json here, and only if it failed, conditionally load the block below"); + auto* scriptCanvasAssetTarget = assetTarget.GetAs(); + AZ_Assert(scriptCanvasAssetTarget, "This should be a ScriptCanvasAsset, as this is the only type we process!"); - if (scriptCanvasAsset && m_serializeContext) + if (scriptCanvasAssetTarget && m_serializeContext && streamSource) { - stream->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... - bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*stream, scriptCanvasAsset->GetScriptCanvasData(), m_serializeContext, AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); - return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error; + AZ::JsonDeserializerSettings settings; + // more mapping stuff + settings.m_serializeContext = m_serializeContext; + streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // presume JSON serialization... + if (JSRU::LoadObjectFromStreamByType + ( scriptCanvasAssetTarget + , azrtti_typeid() + , *streamSource + , &settings).IsSuccess()) + { + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } + else + { + // ...if there is a failure, check if it is saved in the old format + streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... + bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*streamSource, scriptCanvasAssetTarget->GetScriptCanvasData() + , m_serializeContext + , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); + + return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error; + } } + return AZ::Data::AssetHandler::LoadResult::Error; } @@ -111,25 +127,20 @@ namespace ScriptCanvasEditor bool ScriptCanvasAssetHandler::SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, [[maybe_unused]] AZ::DataStream::StreamType streamType) { - namespace JSR = AZ::JsonSerializationResult; - - if (assetData && m_serializeContext) - { + namespace JSRU = AZ::JsonSerializationUtils; + using namespace ScriptCanvas; + + if (assetData && stream && m_serializeContext) + { AZ::JsonSerializerSettings settings; settings.m_keepDefaults = false; settings.m_serializeContext = m_serializeContext; - rapidjson::Document document; - - if (AZ::JsonSerialization::Store(document, document.GetAllocator(), assetData->GetScriptCanvasData(), settings).GetProcessing() != JSR::Processing::Halted) - { - // \todo replace with with exact function from JsonUtils.cpp once it is moved to AzToolsFramework - AZ::IO::RapidJSONStreamWriter jsonStreamWriter(stream); - rapidjson::PrettyWriter writer(jsonStreamWriter); - return document.Accept(writer); - } + return JSRU::SaveObjectToStream(&assetData->GetScriptCanvasData(), *stream, nullptr, &settings).IsSuccess(); + } + else + { + return false; } - - return false; } void ScriptCanvasAssetHandler::DestroyAsset(AZ::Data::AssetPtr ptr) From 0270fb7fbef46a923fbb6ae03fd5e2397483b0e2 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 17 Aug 2021 13:47:20 -0700 Subject: [PATCH 03/27] Initial saving/loading of JSON serialization of sc editor assets Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Serialization/Json/BaseJsonSerializer.cpp | 22 ++-- .../Serialization/Json/BaseJsonSerializer.h | 3 +- .../Serialization/Json/JsonDeserializer.cpp | 20 ++-- .../Serialization/Json/JsonDeserializer.h | 10 +- .../Serialization/Json/JsonSerialization.cpp | 4 +- .../Serialization/Json/JsonSerializer.cpp | 29 ++--- .../Serialization/Json/JsonSerializer.h | 15 ++- .../Serialization/Json/JsonUtils.cpp | 2 +- .../Code/Editor/Assets/ScriptCanvasAsset.cpp | 2 + .../Assets/ScriptCanvasAssetHandler.cpp | 57 ++++++---- .../AutoGen/ScriptCanvasGrammar_Header.jinja | 16 ++- .../AutoGen/ScriptCanvasGrammar_Source.jinja | 22 ++-- .../Code/Include/ScriptCanvas/Core/Core.h | 4 +- .../Code/Include/ScriptCanvas/Core/Datum.cpp | 29 ++++- .../Code/Include/ScriptCanvas/Core/Datum.h | 19 +++- .../Include/ScriptCanvas/Core/GraphData.cpp | 10 +- .../Include/ScriptCanvas/Core/GraphData.h | 1 + .../Code/Include/ScriptCanvas/Core/Node.cpp | 7 +- .../Code/Include/ScriptCanvas/Core/Node.h | 16 +-- .../ScriptCanvas/Core/SerializationListener.h | 26 +++++ .../Data/BehaviorContextObject.cpp | 22 +--- .../ScriptCanvas/Data/BehaviorContextObject.h | 15 +-- .../Libraries/Core/EBusEventHandler.cpp | 10 +- .../Libraries/Core/EBusEventHandler.h | 2 + .../ScriptCanvas/Libraries/Core/Method.cpp | 13 ++- .../ScriptCanvas/Libraries/Core/Method.h | 8 +- .../Libraries/Core/MethodOverloaded.cpp | 17 ++- .../Libraries/Core/MethodOverloaded.h | 7 +- .../Serialization/DatumSerializer.cpp | 11 +- .../Serialization/GraphDataSerializer.cpp | 100 ++++++++++++++++++ .../Serialization/GraphDataSerializer.h | 37 +++++++ .../RuntimeVariableSerializer.cpp | 1 + .../Code/Source/SystemComponent.cpp | 15 ++- 33 files changed, 418 insertions(+), 154 deletions(-) create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 56933e464a..4a02563f3a 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -213,9 +213,13 @@ namespace AZ void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags) { bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance; + JsonDeserializer::UseTypeDeserializer useCustom = (flags & ContinuationFlags::NoTypeSerializer) == ContinuationFlags::NoTypeSerializer + ? JsonDeserializer::UseTypeDeserializer::No + : JsonDeserializer::UseTypeDeserializer::Yes; + return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer - ? JsonDeserializer::LoadToPointer(object, typeId, value, context) - : JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, context); + ? JsonDeserializer::LoadToPointer(object, typeId, value, useCustom, context) + : JsonDeserializer::Load(object, typeId, value, loadAsNewInstance, useCustom, context); } JsonSerializationResult::ResultCode BaseJsonSerializer::ContinueStoring( @@ -224,11 +228,15 @@ namespace AZ { using namespace JsonSerializationResult; + JsonSerializer::UseTypeSerializer useCustom = (flags & ContinuationFlags::NoTypeSerializer) == ContinuationFlags::NoTypeSerializer + ? JsonSerializer::UseTypeSerializer::No + : JsonSerializer::UseTypeSerializer::Yes; + if ((flags & ContinuationFlags::ReplaceDefault) == ContinuationFlags::ReplaceDefault && !context.ShouldKeepDefaults()) { if ((flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer) { - return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, context); + return JsonSerializer::StoreFromPointer(output, object, nullptr, typeId, useCustom, context); } else { @@ -241,19 +249,19 @@ namespace AZ { return result; } - return result.Combine(JsonSerializer::Store(output, object, nullptr, typeId, context)); + return result.Combine(JsonSerializer::Store(output, object, nullptr, typeId, useCustom, context)); } else { void* defaultObjectPtr = AZStd::any_cast(&newDefaultObject); - return JsonSerializer::Store(output, object, defaultObjectPtr, typeId, context); + return JsonSerializer::Store(output, object, defaultObjectPtr, typeId, useCustom, context); } } } return (flags & ContinuationFlags::ResolvePointer) == ContinuationFlags::ResolvePointer ? - JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, context) : - JsonSerializer::Store(output, object, defaultObject, typeId, context); + JsonSerializer::StoreFromPointer(output, object, defaultObject, typeId, useCustom, context) : + JsonSerializer::Store(output, object, defaultObject, typeId, useCustom, context); } JsonSerializationResult::ResultCode BaseJsonSerializer::LoadTypeId(Uuid& typeId, const rapidjson::Value& input, diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index fc35bdcf85..12ae01799c 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -162,9 +162,10 @@ namespace AZ None = 0, //! No extra flags. ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance. ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one. - LoadAsNewInstance = 1 << 2 //! Treats the value as if it's a newly created instance. This may trigger serializers marked with + LoadAsNewInstance = 1 << 2, //! Treats the value as if it's a newly created instance. This may trigger serializers marked with //! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to //! an array. + NoTypeSerializer = 1 << 3, //! Ignore the custom/specific serializer for the TypeId }; enum class OperationFlags diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 840034e52f..dcc0550107 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -38,7 +38,8 @@ namespace AZ } JsonSerializationResult::ResultCode JsonDeserializer::Load( - void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context) + void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, UseTypeDeserializer custom, + JsonDeserializerContext& context) { using namespace AZ::JsonSerializationResult; @@ -48,8 +49,8 @@ namespace AZ "Target object for Json Serialization is pointing to nothing during loading."); } - BaseJsonSerializer* serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); - if (serializer) + if (BaseJsonSerializer* serializer + = (custom == UseTypeDeserializer::Yes ? context.GetRegistrationContext()->GetSerializerForType(typeId) : nullptr)) { return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context); } @@ -70,8 +71,9 @@ namespace AZ // type itself has not been reflected using EnumBuilder. Treat it as an enum. return LoadEnum(object, *classData, value, context); } - serializer = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()); - if (serializer) + + if (BaseJsonSerializer* serializer + = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId())) { return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context); } @@ -101,7 +103,7 @@ namespace AZ } JsonSerializationResult::ResultCode JsonDeserializer::LoadToPointer(void* object, const Uuid& typeId, - const rapidjson::Value& value, JsonDeserializerContext& context) + const rapidjson::Value& value, UseTypeDeserializer useCustom, JsonDeserializerContext& context) { using namespace JsonSerializationResult; @@ -134,7 +136,7 @@ namespace AZ const SerializeContext::ClassData* resolvedClassData = context.GetSerializeContext()->FindClassData(resolvedTypeId); if (resolvedClassData) { - status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, context); + status = JsonDeserializer::Load(*objectPtr, resolvedTypeId, value, true, useCustom, context); *objectPtr = resolvedClassData->m_azRtti->Cast(*objectPtr, typeId); @@ -171,11 +173,11 @@ namespace AZ } AZ_Assert(classElement.m_azRtti->GetTypeId() == classElement.m_typeId, "Type id mismatch during deserialization of a json file. (%s vs %s)"); - return LoadToPointer(object, classElement.m_typeId, value, context); + return LoadToPointer(object, classElement.m_typeId, value, UseTypeDeserializer::Yes, context); } else { - return Load(object, classElement.m_typeId, value, false, context); + return Load(object, classElement.m_typeId, value, false, UseTypeDeserializer::Yes, context); } } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h index ea236fe93c..d0a07b1a74 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.h @@ -28,6 +28,11 @@ namespace AZ FullyProcessed, ContinueProcessing }; + enum class UseTypeDeserializer : bool + { + No, + Yes + }; enum class TypeIdDetermination : u8 { ExplicitTypeId, // Type id was explicitly defined using "$type". @@ -55,10 +60,11 @@ namespace AZ JsonDeserializer(JsonDeserializer&& rhs) = delete; static JsonSerializationResult::ResultCode Load( - void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, JsonDeserializerContext& context); + void* object, const Uuid& typeId, const rapidjson::Value& value, bool isNewInstance, UseTypeDeserializer useCustom, + JsonDeserializerContext& context); static JsonSerializationResult::ResultCode LoadToPointer(void* object, const Uuid& typeId, const rapidjson::Value& value, - JsonDeserializerContext& context); + UseTypeDeserializer useCustom, JsonDeserializerContext& context); static JsonSerializationResult::ResultCode LoadWithClassElement(void* object, const rapidjson::Value& value, const SerializeContext::ClassElement& classElement, JsonDeserializerContext& context); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp index 8ade30cc6c..bc07f684f6 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerialization.cpp @@ -245,7 +245,7 @@ namespace AZ { StackedString path(StackedString::Format::JsonPointer); JsonDeserializerContext context(settings); - result = JsonDeserializer::Load(object, objectType, root, false, context); + result = JsonDeserializer::Load(object, objectType, root, false, JsonDeserializer::UseTypeDeserializer::Yes, context); } return result; } @@ -322,7 +322,7 @@ namespace AZ JsonSerializerContext context(settings, allocator); StackedString path(StackedString::Format::ContextPath); - result = JsonSerializer::Store(output, object, defaultObject, objectType, context); + result = JsonSerializer::Store(output, object, defaultObject, objectType, JsonSerializer::UseTypeSerializer::Yes, context); } return result; } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp index 1fa0dd3c44..80a81181e5 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp @@ -20,7 +20,7 @@ namespace AZ { JsonSerializationResult::ResultCode JsonSerializer::Store(rapidjson::Value& output, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context) + const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context) { using namespace JsonSerializationResult; @@ -32,8 +32,8 @@ namespace AZ // First check if there's a generic serializer registered for this. This makes it possible to use serializers that // are not (directly) registered with the Serialize Context. - auto serializer = context.GetRegistrationContext()->GetSerializerForType(typeId); - if (serializer) + if (BaseJsonSerializer* serializer + = (custom == UseTypeSerializer::Yes ? context.GetRegistrationContext()->GetSerializerForType(typeId) : nullptr)) { // Start by setting the object to be an explicit default. output.SetObject(); @@ -57,17 +57,18 @@ namespace AZ "No factory available to create a default object for comparison."); } void* defaultObjectPtr = AZStd::any_cast(&defaultObjectInstance); - ResultCode conversionResult = StoreWithClassData(output, object, defaultObjectPtr, *classData, StoreTypeId::No, context); + ResultCode conversionResult = StoreWithClassData(output, object, defaultObjectPtr, *classData, StoreTypeId::No + , UseTypeSerializer::Yes, context); return ResultCode::Combine(result, conversionResult); } else { - return StoreWithClassData(output, object, defaultObject, *classData, StoreTypeId::No, context); + return StoreWithClassData(output, object, defaultObject, *classData, StoreTypeId::No, custom, context); } } JsonSerializationResult::ResultCode JsonSerializer::StoreFromPointer(rapidjson::Value& output, const void* object, - const void* defaultObject, const Uuid& typeId, JsonSerializerContext& context) + const void* defaultObject, const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context) { using namespace JsonSerializationResult; @@ -85,19 +86,21 @@ namespace AZ AZ_Assert(classData->m_azRtti->GetTypeId() == typeId, "Type id mismatch in '%s' during serialization to a json file. (%s vs %s)", classData->m_name, classData->m_azRtti->GetTypeId().ToString().c_str(), typeId.ToString().c_str()); - return StoreWithClassDataFromPointer(output, object, defaultObject, *classData, context); + return StoreWithClassDataFromPointer(output, object, defaultObject, *classData, custom, context); } JsonSerializationResult::ResultCode JsonSerializer::StoreWithClassData(rapidjson::Value& node, const void* object, const void* defaultObject, const SerializeContext::ClassData& classData, StoreTypeId storeTypeId, - JsonSerializerContext& context) + UseTypeSerializer custom, JsonSerializerContext& context) { using namespace JsonSerializationResult; // Start by setting the object to be an explicit default. node.SetObject(); - auto serializer = context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId); + auto serializer = custom == UseTypeSerializer::Yes + ? context.GetRegistrationContext()->GetSerializerForType(classData.m_typeId) : nullptr; + if (serializer) { ResultCode result = serializer->Store(node, object, defaultObject, classData.m_typeId, context); @@ -153,7 +156,7 @@ namespace AZ } JsonSerializationResult::ResultCode JsonSerializer::StoreWithClassDataFromPointer(rapidjson::Value& output, const void* object, - const void* defaultObject, const SerializeContext::ClassData& classData, JsonSerializerContext& context) + const void* defaultObject, const SerializeContext::ClassData& classData, UseTypeSerializer custom, JsonSerializerContext& context) { using namespace JsonSerializationResult; @@ -176,7 +179,7 @@ namespace AZ } else { - return StoreWithClassData(output, object, defaultObject, *resolvedClassData, storeTypeId, context); + return StoreWithClassData(output, object, defaultObject, *resolvedClassData, storeTypeId, custom, context); } } @@ -221,8 +224,8 @@ namespace AZ { rapidjson::Value value; ResultCode result = classElement.m_flags & SerializeContext::ClassElement::FLG_POINTER ? - StoreWithClassDataFromPointer(value, object, defaultObject, *elementClassData, context): - StoreWithClassData(value, object, defaultObject, *elementClassData, StoreTypeId::No, context); + StoreWithClassDataFromPointer(value, object, defaultObject, *elementClassData, UseTypeSerializer::Yes, context): + StoreWithClassData(value, object, defaultObject, *elementClassData, StoreTypeId::No, UseTypeSerializer::Yes, context); if (result.GetProcessing() != Processing::Halted) { if (parentNode.IsObject()) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.h index 0ccf020cee..22dd768ec5 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.h @@ -26,6 +26,11 @@ namespace AZ No, Yes }; + enum class UseTypeSerializer : bool + { + No, + Yes + }; enum class ResolvePointerResult { FullyProcessed, @@ -41,16 +46,18 @@ namespace AZ JsonSerializer(JsonSerializer&& rhs) = delete; static JsonSerializationResult::ResultCode Store(rapidjson::Value& output, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context); + const Uuid& typeId, UseTypeSerializer useCustom, JsonSerializerContext& context); static JsonSerializationResult::ResultCode StoreFromPointer(rapidjson::Value& output, const void* object, const void* defaultObject, - const Uuid& typeId, JsonSerializerContext& context); + const Uuid& typeId, UseTypeSerializer custom, JsonSerializerContext& context); static JsonSerializationResult::ResultCode StoreWithClassData(rapidjson::Value& node, const void* object, const void* defaultObject, - const SerializeContext::ClassData& classData, StoreTypeId storeTypeId, JsonSerializerContext& context); + const SerializeContext::ClassData& classData, StoreTypeId storeTypeId, UseTypeSerializer custom, + JsonSerializerContext& context); static JsonSerializationResult::ResultCode StoreWithClassDataFromPointer(rapidjson::Value& output, const void* object, - const void* defaultObject, const SerializeContext::ClassData& classData, JsonSerializerContext& context); + const void* defaultObject, const SerializeContext::ClassData& classData, UseTypeSerializer custom, + JsonSerializerContext& context); static JsonSerializationResult::ResultCode StoreWithClassElement(rapidjson::Value& parentNode, const void* object, const void* defaultObject, const SerializeContext::ClassElement& classElement, JsonSerializerContext& context); diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp index 89cf667958..49a902de54 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp @@ -333,7 +333,7 @@ namespace AZ // validate class name auto classData = loadSettings.m_serializeContext->FindClassData(classId); - if (azstricmp(classData->m_name, className) != 0) + if (!classData || azstricmp(classData->m_name, className) != 0) { return AZ::Failure(AZStd::string::format("Try to load class %s from class %s data", classData->m_name, className)); } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp index adada5791e..8d9f575586 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp @@ -114,11 +114,13 @@ namespace ScriptCanvasEditor ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() { + AZ_Assert(m_data != nullptr, "data not initialized"); return *m_data; } const ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() const { + AZ_Assert(m_data != nullptr, "data not initialized"); return *m_data; } } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index ee78a71772..9af12facca 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -76,7 +76,7 @@ namespace ScriptCanvasEditor AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData ( const AZ::Data::Asset& assetTarget , AZStd::shared_ptr streamSource - , const AZ::Data::AssetFilterCB& assetLoadFilterCB) + , [[maybe_unused]] const AZ::Data::AssetFilterCB& assetLoadFilterCB) { namespace JSRU = AZ::JsonSerializationUtils; using namespace ScriptCanvas; @@ -86,30 +86,43 @@ namespace ScriptCanvasEditor if (scriptCanvasAssetTarget && m_serializeContext && streamSource) { - AZ::JsonDeserializerSettings settings; - // more mapping stuff - settings.m_serializeContext = m_serializeContext; streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - // presume JSON serialization... - if (JSRU::LoadObjectFromStreamByType - ( scriptCanvasAssetTarget - , azrtti_typeid() - , *streamSource - , &settings).IsSuccess()) - { - return AZ::Data::AssetHandler::LoadResult::LoadComplete; - } - else - { - // ...if there is a failure, check if it is saved in the old format - streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... - bool loadSuccess = AZ::Utils::LoadObjectFromStreamInPlace(*streamSource, scriptCanvasAssetTarget->GetScriptCanvasData() - , m_serializeContext - , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); + auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData(); + AZStd::vector byteBuffer(streamSource->GetLength()); + AZ::IO::ByteContainerStream byteStreamSource(&byteBuffer); + const size_t bytesRead = streamSource->Read(byteBuffer.size(), byteBuffer.data()); - return loadSuccess ? AZ::Data::AssetHandler::LoadResult::LoadComplete : AZ::Data::AssetHandler::LoadResult::Error; + if (bytesRead == streamSource->GetLength()) + { + byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + AZ::JsonDeserializerSettings settings; + // \todo more mapping stuff needs to go in the settings + settings.m_serializeContext = m_serializeContext; + byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // attempt JSON deserialization... + if (JSRU::LoadObjectFromStreamByType + ( &scriptCanvasDataTarget + , azrtti_typeid() + , byteStreamSource + , &settings).IsSuccess()) + { + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) + else + { + // ...if there is a failure, check if it is saved in the old format + byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... + if (AZ::Utils::LoadObjectFromStreamInPlace(byteStreamSource, scriptCanvasAssetTarget->GetScriptCanvasData() + , m_serializeContext + , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES))) + { + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } + } } +#endif } return AZ::Data::AssetHandler::LoadResult::Error; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja index 00c23b9f35..ebf647c7e9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja @@ -43,9 +43,19 @@ SPDX-License-Identifier: Apache-2.0 OR MIT namespace {{attribute_Namespace}} { {% endif %} - {% set className = Class.attrib['Name'] %} -{% set baseClass = Class.attrib['Base'] %} +{% if Class.attrib['Base'] is defined %} +{% if Class.attrib['Base'].split(';')|length > 1 %} +{% set baseClass = Class.attrib['Base'].split(';')[0] %} +{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %} +{% else %} +{% set baseClass = Class.attrib['Base'] %} +{% set baseClasses = Class.attrib['Base'] %} +{% endif %} +{% else %} +{% set baseClass = "ScriptCanvas::Node" %} +{% set baseClasses = "ScriptCanvas::Node" %} +{% endif %} ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -66,7 +76,7 @@ namespace {{attribute_Namespace}} // You must #include the generated header into the source header #define SCRIPTCANVAS_NODE_{{ className }} \ public: \ - AZ_COMPONENT({{ className }}, "{{ classUuid }}"{% if baseClass is defined %}, {{ baseClass }}{% endif %}); \ + AZ_COMPONENT({{ className }}, "{{ classUuid }}", {{ baseClasses}} ); \ static void Reflect(AZ::ReflectContext* reflection); \ void ConfigureSlots() override; \ bool RequiresDynamicSlotOrdering() const override; \ diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index 205e6ebd8c..18b7fac688 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -26,12 +26,22 @@ SPDX-License-Identifier: Apache-2.0 OR MIT #include "{{ xml.attrib['Include'] }}" {% for Class in xml.iter('Class') %} +{% if Class.attrib['Base'] is defined %} +{% if Class.attrib['Base'].split(';')|length > 1 %} +{% set baseClass = Class.attrib['Base'].split(';')[0] %} +{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %} +{% else %} +{% set baseClass = Class.attrib['Base'] %} +{% set baseClasses = Class.attrib['Base'] %} +{% endif %} +{% else %} +{% set baseClass = "ScriptCanvas::Node" %} +{% set baseClasses = "ScriptCanvas::Node" %} +{% endif %} void {{ Class.attrib['QualifiedName'] }}::ConfigureSlots() { -{% if Class.attrib['Base'] is defined %} - {{ Class.attrib['Base'] }}::ConfigureSlots(); + {{ baseClass }}::ConfigureSlots(); -{% endif %} {% for Property in Class.iter('Property') %} {% if Property.attrib['IsInput'] | booleanTrue %} // {{ Property.attrib['Name'] }} @@ -194,13 +204,11 @@ void {{ Class.attrib['QualifiedName'] }}::Reflect(AZ::ReflectContext* context) {% endfor %} {% endif %} -{% if Class.attrib['Base'] is defined %} - static_assert((std::is_base_of::value), "Script Canvas nodes require the first base class to be derived from ScriptCanvas::Node"); + static_assert((std::is_base_of::value), "Script Canvas nodes require the first base class to be derived from ScriptCanvas::Node"); -{% endif %} if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { - serializeContext->Class<{{ Class.attrib['QualifiedName'] }}{% if Class.attrib['Base'] is defined %}, {{ Class.attrib['Base'] }}{% endif %}>() + serializeContext->Class<{{ Class.attrib['QualifiedName'] }}, {{ baseClass }}>() {% if Class.attrib['EventHandler'] is defined %} ->EventHandler<{{ Class.attrib['EventHandler'] }}>() {% endif %} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index 5e4d11ac65..76542d6097 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -24,6 +24,8 @@ #include #include +#define OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED + namespace AZ { class Entity; @@ -94,7 +96,7 @@ namespace ScriptCanvas struct VersionData { - AZ_TYPE_INFO(VersionData, "{14C629F6-467B-46FE-8B63-48FDFCA42175}"); + AZ_TYPE_INFO(VersionData, "{52036892-DA63-4199-AC6A-9BAFE6B74EFC}"); static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index e4569af820..c36110ef92 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -2041,7 +2041,27 @@ namespace ScriptCanvas } } - void Datum::OnWriteEnd() + void Datum::OnSerializeBegin() + { + if (m_type.GetType() == Data::eType::BehaviorContextObject) + { + if (BehaviorContextObjectPtr ptr = (*AZStd::any_cast(&m_storage.value))) + { + ptr->OnSerializeBegin(); + } + else + { + AZ_Error("ScriptCanvas", false, AZStd::string::format("Datum type (%s) failed to serialized, did not store BehaviorContextObjectPtr properly", m_type.GetAZType().ToString().c_str()).c_str()); + } + } + } + + void Datum::OnReadBegin() + { + OnSerializeBegin(); + } + + void Datum::OnDeserialize() { if (m_type.GetType() == Data::eType::BehaviorContextObject) { @@ -2059,11 +2079,16 @@ namespace ScriptCanvas } else { - AZ_Error("Script Canvas", false, AZStd::string::format("Datum type (%s) de-serialized, but no such class found in the behavior context", m_type.GetAZType().ToString().c_str()).c_str()); + AZ_Error("ScriptCanvas", false, AZStd::string::format("Datum type (%s) de-serialized, but no such class found in the behavior context", m_type.GetAZType().ToString().c_str()).c_str()); } } } + void Datum::OnWriteEnd() + { + OnSerializeEnd(); + } + void Datum::Reflect(AZ::ReflectContext* reflection) { if (auto serializeContext = azrtti_cast(reflection)) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index 4cbc25b500..3ad09e2297 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -8,14 +8,15 @@ #pragma once +#include #include #include #include #include +#include +#include #include #include -#include -#include namespace AZ { @@ -33,11 +34,12 @@ namespace ScriptCanvas /// A Datum is used to provide generic storage for all data types in ScriptCanvas, and provide a common interface to accessing, modifying, and displaying them /// in the editor, regardless of their actual ScriptCanvas or BehaviorContext type. class Datum final + : public SerializationListener { friend class AZ::DatumSerializer; public: - AZ_TYPE_INFO(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}"); + AZ_RTTI(Datum, "{8B836FC0-98A8-4A81-8651-35C7CA125451}", SerializationListener); AZ_CLASS_ALLOCATOR(Datum, AZ::SystemAllocator, 0); enum class eOriginality : int @@ -237,6 +239,13 @@ namespace ScriptCanvas class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler { public: + /// Called after we are done writing to the instance pointed by classPtr. + void OnReadBegin(void* classPtr) override + { + Datum* datum = reinterpret_cast(classPtr); + datum->OnReadBegin(); + } + /// Called after we are done writing to the instance pointed by classPtr. void OnWriteEnd(void* classPtr) override { @@ -341,6 +350,10 @@ namespace ScriptCanvas void OnDatumEdited(); + void OnSerializeBegin() override; + + void OnDeserialize() override; + void OnReadBegin(); void OnWriteEnd(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp index 9bed478d74..d8fd409147 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp @@ -25,9 +25,7 @@ namespace ScriptCanvas /// Called to rebuild the Endpoint map void OnWriteEnd(void* classPtr) override { - auto* graphData = reinterpret_cast(classPtr); - graphData->BuildEndpointMap(); - graphData->LoadDependentAssets(); + reinterpret_cast(classPtr)->OnDeserialized(); } }; @@ -215,4 +213,10 @@ namespace ScriptCanvas m_dependentAssets.clear(); } + + void GraphData::OnDeserialized() + { + BuildEndpointMap(); + LoadDependentAssets(); + } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.h index f09098ca17..cdd23bbdda 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.h @@ -37,6 +37,7 @@ namespace ScriptCanvas void BuildEndpointMap(); void Clear(bool deleteData = false); void LoadDependentAssets(); + void OnDeserialized(); using NodeContainer = AZStd::unordered_set; using ConnectionContainer = AZStd::vector; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 6e87e52f87..5af59fc166 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -67,7 +67,7 @@ namespace ScriptCanvas void OnWriteEnd(void* objectPtr) override { auto node = reinterpret_cast(objectPtr); - node->RebuildInternalState(); + node->OnDeserialize(); } }; @@ -2616,6 +2616,11 @@ namespace ScriptCanvas } } + void Node::OnDeserialize() + { + RebuildInternalState(); + } + void Node::OnEndpointConnected(const Endpoint& endpoint) { const SlotId& currentSlotId = EndpointNotificationBus::GetCurrentBusId()->GetSlotId(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index bf3e17156b..298eff5222 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -14,25 +14,23 @@ #include #include #include - +#include #include #include #include #include -#include #include #include #include +#include #include +#include #include +#include #include #include -#include #include -#include - -#include - +#include #define SCRIPT_CANVAS_CALL_ON_INDEX_SEQUENCE(lambdaInterior)\ int dummy[]{ 0, ( lambdaInterior , 0)... };\ @@ -401,6 +399,7 @@ namespace ScriptCanvas , public DatumNotificationBus::Handler , public NodeRequestBus::Handler , public EndpointNotificationBus::MultiHandler + , public SerializationListener { friend class Graph; friend class RuntimeComponent; @@ -472,7 +471,7 @@ namespace ScriptCanvas public: - AZ_COMPONENT(Node, "{52B454AE-FA7E-4FE9-87D3-A1CAB235C691}"); + AZ_COMPONENT(Node, "{52B454AE-FA7E-4FE9-87D3-A1CAB235C691}", SerializationListener); static void Reflect(AZ::ReflectContext* reflection); Node(); @@ -821,6 +820,7 @@ namespace ScriptCanvas ////////////////////////////////////////////////////////////////////////// protected: + void OnDeserialize() override; virtual void OnReconfigurationBegin() {} virtual void OnReconfigurationEnd() {} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h new file mode 100644 index 0000000000..d53e66f21b --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +namespace ScriptCanvas +{ + class SerializationListener + { + public: + AZ_RTTI(SerializationListener, "{CA4EE281-30B3-4928-BCD8-9305CE75E463}"); + virtual ~SerializationListener() = 0 {} + + virtual void OnSerializeBegin() {} + virtual void OnSerializeEnd() {} + + virtual void OnDeserialize() {} + }; + + using SerializationListeners = AZStd::vector; +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp index 09d356a2f0..2abeec6266 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp @@ -17,7 +17,7 @@ namespace ScriptCanvas { - void BehaviorContextObject::OnReadBegin() + void BehaviorContextObject::OnSerializeBegin() { if (!IsOwned()) { @@ -25,18 +25,12 @@ namespace ScriptCanvas } } - void BehaviorContextObject::OnWriteEnd() - { - // Id Remapping invokes this method as well, not just serializing from an ObjectStream - } - void BehaviorContextObject::Reflect(AZ::ReflectContext* reflection) { if (auto serializeContext = azrtti_cast(reflection)) { serializeContext->Class() ->Version(0) - ->EventHandler() ->Field("m_flags", &BehaviorContextObject::m_flags) ->Field("m_object", &BehaviorContextObject::m_object) ; @@ -55,24 +49,11 @@ namespace ScriptCanvas } } - void BehaviorContextObject::SerializeContextEventHandler::OnReadBegin(void* classPtr) - { - BehaviorContextObject* object = reinterpret_cast(classPtr); - object->OnReadBegin(); - } - - void BehaviorContextObject::SerializeContextEventHandler::OnWriteEnd(void* classPtr) - { - BehaviorContextObject* object = reinterpret_cast(classPtr); - object->OnWriteEnd(); - } - BehaviorContextObjectPtr BehaviorContextObject::CloneObject(const AZ::BehaviorClass& behaviorClass) { if (SystemRequestBus::HasHandlers()) { AZStd::vector buffer; - { bool wasOwned = IsOwned(); m_flags |= Flags::Owned; @@ -87,7 +68,6 @@ namespace ScriptCanvas } AZ::IO::ByteContainerStream> readStream(&buffer); - BehaviorContextObject* newObject = CreateDefault(behaviorClass); AZ::Utils::LoadObjectFromStreamInPlace(readStream, (*newObject)); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index ca4500eccc..8cb04801fc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -29,6 +29,7 @@ namespace ScriptCanvas class BehaviorContextObject final { friend struct AZStd::IntrusivePtrCountPolicy; + friend class Datum; public: AZ_TYPE_INFO(BehaviorContextObject, "{B735214D-5182-4536-B748-61EC83C1F007}"); @@ -69,16 +70,6 @@ namespace ScriptCanvas Reference = 1 << 3, }; - class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler - { - public: - /// Called right before we start reading from the instance pointed by classPtr. - void OnReadBegin(void* classPtr) override; - - /// Called after we are done writing to the instance pointed by classPtr. - void OnWriteEnd(void* classPtr) override; - }; - template static AZ::BehaviorObject InvokeConstructor(const AZ::BehaviorClass& behaviorClass, void* resultPtr, Args&&... args); @@ -128,9 +119,7 @@ namespace ScriptCanvas AZ_FORCE_INLINE bool IsOwned() const; - void OnReadBegin(); - - void OnWriteEnd(); + void OnSerializeBegin(); AZ_FORCE_INLINE void add_ref(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp index af583738da..bfcb629225 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp @@ -602,13 +602,21 @@ namespace ScriptCanvas } } - void EBusEventHandler::OnWriteEnd() + void EBusEventHandler::OnDeserialize() { AZStd::lock_guard lock(m_mutex); if (!m_ebus) { CreateHandler(m_ebusName); } + + /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super + Node::OnDeserialize(); + } + + void EBusEventHandler::OnWriteEnd() + { + OnDeserialize(); } NodeTypeIdentifier EBusEventHandler::GetOutputNodeType(const SlotId& slotId) const diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h index eb905b7c90..b36636fe1c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h @@ -138,6 +138,8 @@ namespace ScriptCanvas void SetAutoConnectToGraphOwner(bool enabled); + void OnDeserialize(); + void OnWriteEnd(); AZStd::string GetNodeName() const override diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 9701e346be..5a732a1185 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -313,6 +313,7 @@ namespace ScriptCanvas } PopulateNodeType(); + m_warnOnMissingFunction = true; } bool Method::InitializeOverloaded([[maybe_unused]] const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName) @@ -739,10 +740,11 @@ namespace ScriptCanvas return TupleType{ nullptr, MethodType::Count, EventType::Count, nullptr }; } - void Method::OnWriteEnd() + void Method::OnDeserialize() { AZStd::lock_guard lock(m_mutex); + m_warnOnMissingFunction = true; const AZ::BehaviorClass* bcClass{}; const AZ::BehaviorMethod* method{}; EventType eventType; @@ -758,13 +760,20 @@ namespace ScriptCanvas { AZ_Warning("ScriptCanvas", !m_warnOnMissingFunction, "method node failed to deserialize properly"); } - } if (m_resultSlotIDs.empty()) { m_resultSlotIDs.emplace_back(SlotId{}); } + + /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super + Node::OnDeserialize(); + } + + void Method::OnWriteEnd() + { + OnDeserialize(); } bool Method::BranchesOnResult() const diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index 41d4adcb84..b44539d915 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -22,7 +22,6 @@ namespace AZ namespace ScriptCanvas { - AZ::Outcome IsExposable(const AZ::BehaviorMethod& method); Grammar::FunctionPrototype ToSignature(const AZ::BehaviorMethod& method); @@ -31,7 +30,8 @@ namespace ScriptCanvas { namespace Core { - class Method : public Node + class Method + : public Node { public: AZ_COMPONENT(Method, "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF}", Node); @@ -107,6 +107,8 @@ namespace ScriptCanvas SlotId GetBusSlotId() const; + void OnDeserialize(); + void OnWriteEnd(); virtual bool IsMethodOverloaded() const { return false; } @@ -180,7 +182,7 @@ namespace ScriptCanvas AZStd::vector m_inputSlots; AZStd::vector m_resultSlotIDs; AZStd::recursive_mutex m_mutex; // post-serialization - bool m_warnOnMissingFunction = true; + bool m_warnOnMissingFunction = false; Method(const Method&) = delete; }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp index c902d279bc..f20f79a6b1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp @@ -397,20 +397,16 @@ namespace ScriptCanvas return signature; } - void MethodOverloaded::OnReadBegin() - { - } - - void MethodOverloaded::OnReadEnd() - { - } - void MethodOverloaded::OnWriteBegin() { - SetWarnOnMissingFunction(false); } void MethodOverloaded::OnWriteEnd() + { + OnDeserialize(); + } + + void MethodOverloaded::OnDeserialize() { AZStd::lock_guard lock(GetMutex()); @@ -462,6 +458,9 @@ namespace ScriptCanvas } SetWarnOnMissingFunction(true); + + /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super + Node::OnDeserialize(); } void MethodOverloaded::SetupMethodData(const AZ::BehaviorMethod* behaviorMethod, const AZ::BehaviorClass* behaviorClass) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h index c15b8f718c..a4d7ea83d8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h @@ -92,12 +92,13 @@ namespace ScriptCanvas Grammar::FunctionPrototype GetInputSignature() const; // SerializeContextReadWriteHandler - void OnReadBegin(); - void OnReadEnd(); + void OnReadBegin() {} + void OnReadEnd() {} void OnWriteBegin(); void OnWriteEnd(); - //// + + void OnDeserialize() override; void SetupMethodData(const AZ::BehaviorMethod* lookupMethod, const AZ::BehaviorClass* lookupClass); void ConfigureContracts(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp index 003ef05774..aecf0f3db7 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -85,7 +85,7 @@ namespace AZ AZ_Assert(azrtti_typeidm_datumLabel)>() == azrtti_typeid() , "m_datumLabel type changed and won't load properly"); - result.Combine( ContinueLoadingFromJsonObjectField + result.Combine(ContinueLoadingFromJsonObjectField ( &label , azrtti_typeidm_datumLabel)>() , inputValue @@ -95,6 +95,7 @@ namespace AZ Datum copy(scType, Datum::eOriginality::Original, AZStd::any_cast(&storage), scType.GetAZType()); copy.SetLabel(label); *outputDatum = copy; + outputDatum->OnDeserialize(); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "DatumSerializer Load finished loading Datum" @@ -124,7 +125,9 @@ namespace AZ ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum"); } } - + + const_cast(inputScriptDataPtr)->OnSerializeBegin(); + JSR::ResultCode result(JSR::Tasks::WriteValue); outputValue.SetObject(); @@ -162,7 +165,7 @@ namespace AZ , inputScriptDataPtr->GetType().GetAZType() , context)); } // datum storage end - + result.Combine(ContinueStoringToJsonObjectField ( outputValue , "label" @@ -171,9 +174,9 @@ namespace AZ , azrtti_typeidm_datumLabel)>() , context)); + const_cast(inputScriptDataPtr)->OnSerializeEnd(); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "DatumSerializer Store finished saving Datum" : "DatumSerializer Store failed to save Datum"); } - } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp new file mode 100644 index 0000000000..ff284fce85 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +using namespace ScriptCanvas; + +namespace GraphDataSerializerCpp +{ + void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners) + { + for (auto& nodeEntity : container) + { + if (nodeEntity) + { + if (auto listener = azrtti_cast(AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity))) + { + listeners.push_back(listener); + } + } + } + } +} + +namespace AZ +{ + AZ_CLASS_ALLOCATOR_IMPL(GraphDataSerializer, SystemAllocator, 0); + + JsonSerializationResult::Result GraphDataSerializer::Load + ( void* outputValue + , [[maybe_unused]] const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid() + , "RuntimeVariableSerializer Load against output typeID that was not GraphData"); + AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output"); + context.GetMetadata().Add(SerializationListeners()); + JSR::ResultCode result(JSR::Tasks::ReadField); + result.Combine(ContinueLoading(outputValue, outputValueTypeId, inputValue, context, ContinuationFlags::NoTypeSerializer)); + auto listeners = context.GetMetadata().Find(); + AZ_Assert(listeners, "Failed to create SerializationListeners"); + GraphDataSerializerCpp::CollectNodes(reinterpret_cast(outputValue)->m_nodes, *listeners); + + for (auto listener : *listeners) + { + listener->OnDeserialize(); + } + + reinterpret_cast(outputValue)->OnDeserialized(); + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "GraphDataSerializer Load finished loading GraphData" + : "GraphDataSerializer Load failed to load GraphData"); + } + + JsonSerializationResult::Result GraphDataSerializer::Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , [[maybe_unused]] const Uuid& valueTypeId + , JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid() + , "RuntimeVariableSerializer Store against output typeID that was not GraphData"); + AZ_Assert(inputValue, "RuntimeVariableSerializer Store against null output"); + context.GetMetadata().Add(SerializationListeners()); + auto listeners = context.GetMetadata().Find(); + GraphDataSerializerCpp::CollectNodes(reinterpret_cast(inputValue)->m_nodes, *listeners); + + for (auto listener : *listeners) + { + listener->OnSerializeBegin(); + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + result.Combine(ContinueStoring(outputValue, inputValue, defaultValue, valueTypeId, context, ContinuationFlags::NoTypeSerializer)); + + for (auto listener : *listeners) + { + listener->OnSerializeEnd(); + } + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "GraphDataSerializer::Store finished storing GraphData" + : "GraphDataSerializer::Store failed to store GraphData"); + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h new file mode 100644 index 0000000000..e7f91eccb3 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace AZ +{ + class GraphDataSerializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(GraphDataSerializer, "{2DFF5794-785F-4434-9314-52BB3EF1D00E}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + + private: + JsonSerializationResult::Result Load + ( void* outputValue + , const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) override; + + JsonSerializationResult::Result Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , const Uuid& valueTypeId, JsonSerializerContext& context) override; + }; +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp index 763206df38..e03a5e4096 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp @@ -50,6 +50,7 @@ namespace AZ } result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context)); + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "RuntimeVariableSerializer Load finished loading RuntimeVariable" : "RuntimeVariableSerializer Load failed to load RuntimeVariable"); diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp index 0a82b8cf2a..9069592755 100644 --- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp @@ -7,7 +7,6 @@ */ #include - #include #include #include @@ -23,8 +22,9 @@ #include #include #include -#include #include +#include +#include #include #include @@ -59,6 +59,7 @@ namespace ScriptCanvas { void SystemComponent::Reflect(AZ::ReflectContext* context) { + VersionData::Reflect(context); Nodeable::Reflect(context); ReflectLibraries(context); @@ -88,13 +89,9 @@ namespace ScriptCanvas if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context)) { - jsonContext->Serializer() - ->HandlesType() - ; - - jsonContext->Serializer() - ->HandlesType() - ; + jsonContext->Serializer()->HandlesType(); + jsonContext->Serializer()->HandlesType(); + jsonContext->Serializer()->HandlesType(); } #if defined(SC_EXECUTION_TRACE_ENABLED) From 88121f3bb4c21dd90d3a199fbfe5281e197e1624 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 17 Aug 2021 14:06:24 -0700 Subject: [PATCH 04/27] move JsonUtils to AzCore Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp | 2 +- .../AzCore}/Serialization/Json/JsonUtils.cpp | 0 .../AzCore}/Serialization/Json/JsonUtils.h | 0 Code/Framework/AzCore/AzCore/azcore_files.cmake | 2 ++ .../AzToolsFramework/aztoolsframework_files.cmake | 2 -- .../Code/Source/BuilderSettings/BuilderSettingManager.cpp | 2 +- Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp | 2 +- Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp | 2 +- .../Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp | 2 +- .../Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp | 2 +- .../Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp | 2 +- .../Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp | 2 +- .../Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp | 2 +- .../Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp | 2 +- .../Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp | 2 +- .../Common/Code/Source/ProfilingCaptureSystemComponent.cpp | 2 +- Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp | 2 +- Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h | 2 +- .../RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp | 2 +- .../RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp | 2 +- Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp | 2 +- .../Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp | 2 +- .../RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp | 2 +- .../RPI.Edit/Material/MaterialPropertyValueSerializer.cpp | 2 +- .../RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp | 2 +- .../Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp | 2 +- Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp | 2 +- .../Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp | 2 +- Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp | 2 +- .../RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp | 2 +- .../Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp | 2 +- Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp | 2 +- Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp | 2 +- Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp | 2 +- Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h | 2 +- Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp | 2 +- .../RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp | 2 +- .../RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp | 2 +- .../Code/Source/Viewport/MaterialViewportComponent.cpp | 2 +- .../Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp | 2 +- .../Code/Editor/Assets/ScriptCanvasAssetHandler.cpp | 2 +- 41 files changed, 39 insertions(+), 39 deletions(-) rename Code/Framework/{AzToolsFramework/AzToolsFramework => AzCore/AzCore}/Serialization/Json/JsonUtils.cpp (100%) rename Code/Framework/{AzToolsFramework/AzToolsFramework => AzCore/AzCore}/Serialization/Json/JsonUtils.h (100%) diff --git a/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp b/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp index 79e0bf86ee..3444484246 100644 --- a/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp +++ b/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp @@ -13,7 +13,7 @@ #include -#include +#include namespace UnitTest { diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp similarity index 100% rename from Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.cpp rename to Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h similarity index 100% rename from Code/Framework/AzToolsFramework/AzToolsFramework/Serialization/Json/JsonUtils.h rename to Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h diff --git a/Code/Framework/AzCore/AzCore/azcore_files.cmake b/Code/Framework/AzCore/AzCore/azcore_files.cmake index 0c95b9d592..cf2dfc7b4a 100644 --- a/Code/Framework/AzCore/AzCore/azcore_files.cmake +++ b/Code/Framework/AzCore/AzCore/azcore_files.cmake @@ -531,6 +531,8 @@ set(FILES Serialization/Json/JsonStringConversionUtils.h Serialization/Json/JsonSystemComponent.h Serialization/Json/JsonSystemComponent.cpp + Serialization/Json/JsonUtils.h + Serialization/Json/JsonUtils.cpp Serialization/Json/MapSerializer.h Serialization/Json/MapSerializer.cpp Serialization/Json/RegistrationContext.h diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake index 0c49da841f..14c5f34f90 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/aztoolsframework_files.cmake @@ -205,8 +205,6 @@ set(FILES PropertyTreeEditor/PropertyTreeEditorComponent.h Render/EditorIntersectorComponent.cpp Render/EditorIntersectorComponent.h - Serialization/Json/JsonUtils.h - Serialization/Json/JsonUtils.cpp Slice/SliceDataFlagsCommand.h Slice/SliceDataFlagsCommand.cpp Slice/SliceUtilities.h diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp index 764a19d549..3493099d4c 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/BuilderSettings/BuilderSettingManager.cpp @@ -37,7 +37,7 @@ #include #include -#include +#include namespace ImageProcessingAtom { diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp index b299108518..d2bcf4b985 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AtomShaderConfig.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include namespace AZ diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp index 397d47ef21..ce01074959 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/AzslCompiler.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include // [GFX TODO] Remove when [ATOM-15472] diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp index 1b3b7c595d..da77df898b 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/GlobalBuildOptions.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp index adec465a9f..caf20e61fb 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/CommonFiles/Preprocessor.cpp @@ -29,7 +29,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp index 6d876c0ad4..21eda31ca2 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/PrecompiledShaderBuilder.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp index d3fa043fa2..cd820d94db 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderAssetBuilder.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp index df0d9b10a2..2fd2779749 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderBuilderUtility.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp index 8bbae7502b..0f06ccaf25 100644 --- a/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp +++ b/Gems/Atom/Asset/Shader/Code/Source/Editor/ShaderVariantAssetBuilder.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp index 4eb5ab0a76..6fbdf5b3f0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/FrameCaptureSystemComponent.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp index da194d4d4e..dd58772f5a 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ProfilingCaptureSystemComponent.cpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp index f0fbf40a14..d5b626917b 100644 --- a/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp +++ b/Gems/Atom/RHI/Code/Source/RHI.Edit/Utils.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h index 22baf5776a..1a62e1753c 100644 --- a/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h +++ b/Gems/Atom/RPI/Code/Include/Atom/RPI.Edit/Common/JsonUtils.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp index 031b928543..c9c477048f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Common/AnyAssetBuilder.cpp @@ -19,7 +19,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp index 70230cfffb..09f6610150 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Material/MaterialBuilder.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp index 2949125fc1..8492843e9a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/Pass/PassBuilder.cpp @@ -11,7 +11,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp b/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp index 24a105a4f4..6cd2709d25 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Builders/ResourcePool/ResourcePoolBuilder.cpp @@ -16,7 +16,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp index 52b56f254a..a944a35162 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialFunctorSourceDataSerializer.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp index 3c702b84a0..060a563c53 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialPropertyValueSerializer.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include namespace AZ { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp index 8d799fe440..9f980287cf 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceData.cpp @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp index 466fd79dd8..307d2bb80f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialSourceDataSerializer.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp index 7fb9d3d70f..0c2e9dca1f 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Edit/Material/MaterialUtils.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp index 15fadd894b..172fb5750a 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/AttachmentReadback.cpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp index 6d470427b5..afb51afe2c 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Pass/PassSystem.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp index 7e5c268112..dbb5a30756 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetrics.cpp @@ -6,7 +6,7 @@ * */ #include -#include +#include namespace AZ { diff --git a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp index 47c8dedd8d..bcfa2bcbff 100644 --- a/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp +++ b/Gems/Atom/RPI/Code/Source/RPI.Public/Shader/Metrics/ShaderMetricsSystem.cpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp index 33b4bc61fe..92e6957e9d 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/AnyAssetBuilderTest.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp index 993bd8ded2..ed04b25ea3 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/PassBuilderTest.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include #include diff --git a/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp b/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp index 2623cade02..c7e030f912 100644 --- a/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp +++ b/Gems/Atom/RPI/Code/Tests.Builders/ResourcePoolBuilderTest.cpp @@ -8,7 +8,7 @@ #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h b/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h index 3b66565f99..56d537f236 100644 --- a/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h +++ b/Gems/Atom/RPI/Code/Tests/Common/JsonTestUtils.h @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include namespace UnitTest diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp index 9b82f501d2..ca41bbac40 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp @@ -19,7 +19,7 @@ #include #include -//#include +//#include namespace UnitTest { using namespace AZ; diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp index fdd8edf5e5..5386af1cfa 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialPropertySerializerTests.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp index 85beba6721..5edf09b67d 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialTypeSourceDataTests.cpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp index ec2f200ff2..24e78b5ad3 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/MaterialViewportComponent.cpp @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include diff --git a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp index f0a8e35699..2a72641050 100644 --- a/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp +++ b/Gems/AtomLyIntegration/AtomBridge/Code/Source/Editor/AssetCollectionAsyncLoaderTestComponent.cpp @@ -13,7 +13,7 @@ #include -#include +#include // Included so we can deduce the asset type from asset paths. #include diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 9af12facca..3f5fd8441f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include From 778ebc39a2b30ecb28a22e60915e61099674c089 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 17 Aug 2021 14:07:13 -0700 Subject: [PATCH 05/27] add listener to cmake files Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index f1215dd580..49da9565f3 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -74,6 +74,7 @@ set(FILES Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp Include/ScriptCanvas/Core/NodeableNodeOverloaded.h Include/ScriptCanvas/Core/NodeFunctionGeneric.h + Include/ScriptCanvas/Core/SerializationListener.h Include/ScriptCanvas/Core/Slot.cpp Include/ScriptCanvas/Core/Slot.h Include/ScriptCanvas/Core/SlotConfigurationDefaults.h @@ -541,6 +542,8 @@ set(FILES Include/ScriptCanvas/Profiler/DrillerEvents.cpp Include/ScriptCanvas/Serialization/DatumSerializer.h Include/ScriptCanvas/Serialization/DatumSerializer.cpp + Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp + Include/ScriptCanvas/Serialization/GraphDataSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp From 1ad182105b1f0d90d93ac087c220fa1f96cd6c91 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 17 Aug 2021 16:40:48 -0700 Subject: [PATCH 06/27] fix memory leak and possible nullptr read Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Assets/ScriptCanvasAssetHandler.cpp | 35 ++++++++++--------- .../GraphValidationDockWidget.cpp | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 3f5fd8441f..7a07902a11 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -88,9 +88,11 @@ namespace ScriptCanvasEditor { streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData(); - AZStd::vector byteBuffer(streamSource->GetLength()); + AZStd::vector byteBuffer; + byteBuffer.resize_no_construct(streamSource->GetLength()); AZ::IO::ByteContainerStream byteStreamSource(&byteBuffer); const size_t bytesRead = streamSource->Read(byteBuffer.size(), byteBuffer.data()); + scriptCanvasDataTarget.m_scriptCanvasEntity.reset(nullptr); if (bytesRead == streamSource->GetLength()) { @@ -98,31 +100,30 @@ namespace ScriptCanvasEditor AZ::JsonDeserializerSettings settings; // \todo more mapping stuff needs to go in the settings settings.m_serializeContext = m_serializeContext; - byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); // attempt JSON deserialization... if (JSRU::LoadObjectFromStreamByType - ( &scriptCanvasDataTarget - , azrtti_typeid() - , byteStreamSource - , &settings).IsSuccess()) + ( &scriptCanvasDataTarget + , azrtti_typeid() + , byteStreamSource + , &settings).IsSuccess()) { return AZ::Data::AssetHandler::LoadResult::LoadComplete; } -#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) - else - { - // ...if there is a failure, check if it is saved in the old format - byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... - if (AZ::Utils::LoadObjectFromStreamInPlace(byteStreamSource, scriptCanvasAssetTarget->GetScriptCanvasData() + +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// + // ...if there is a failure, check if it is saved in the old format + byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... + if (AZ::Utils::LoadObjectFromStreamInPlace + ( byteStreamSource + , scriptCanvasDataTarget , m_serializeContext , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES))) - { - return AZ::Data::AssetHandler::LoadResult::LoadComplete; - } + { + return AZ::Data::AssetHandler::LoadResult::LoadComplete; } +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) } -#endif } return AZ::Data::AssetHandler::LoadResult::Error; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp index 6d29c01ff4..3400f2ea66 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/ValidationPanel/GraphValidationDockWidget.cpp @@ -734,7 +734,7 @@ namespace ScriptCanvasEditor { ui->statusTableView->clearSelection(); - if (auto model = GetActiveData().second->GetModel()) + if (auto model = GetActiveData().second ? GetActiveData().second->GetModel() : nullptr) { model->Clear(); model->RunValidation(m_activeGraphIds.scriptCanvasId); From b813f2fbf4ca7709ddf6c4258d0949ada9d1ed2e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 18 Aug 2021 10:56:02 -0700 Subject: [PATCH 07/27] add compiler flag for object stream support of SC editor assets Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AutoGen/ScriptCanvasGrammar_Source.jinja | 2 ++ .../AutoGen/ScriptCanvasNodeable_Source.jinja | 2 ++ .../Code/Include/ScriptCanvas/Core/Datum.cpp | 14 +++++++++----- .../Code/Include/ScriptCanvas/Core/Datum.h | 6 +++++- .../Code/Include/ScriptCanvas/Core/GraphData.cpp | 4 ++++ .../Code/Include/ScriptCanvas/Core/Node.cpp | 4 ++++ .../Code/Include/ScriptCanvas/Core/Node.h | 2 ++ .../Libraries/Core/EBusEventHandler.cpp | 2 ++ .../ScriptCanvas/Libraries/Core/EBusEventHandler.h | 2 ++ .../Include/ScriptCanvas/Libraries/Core/Method.cpp | 4 ++++ .../Include/ScriptCanvas/Libraries/Core/Method.h | 2 ++ .../Libraries/Core/MethodOverloaded.cpp | 4 ++++ .../ScriptCanvas/Libraries/Core/MethodOverloaded.h | 4 ++++ 13 files changed, 46 insertions(+), 6 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index 18b7fac688..04c030acce 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -210,7 +210,9 @@ void {{ Class.attrib['QualifiedName'] }}::Reflect(AZ::ReflectContext* context) { serializeContext->Class<{{ Class.attrib['QualifiedName'] }}, {{ baseClass }}>() {% if Class.attrib['EventHandler'] is defined %} +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler<{{ Class.attrib['EventHandler'] }}>() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) {% endif %} {% if Class.attrib['Version'] is defined %} ->Version({{ Class.attrib['Version'] }}{% if Class.attrib['VersionConverter'] is defined %}, &{{ Class.attrib['VersionConverter'] }}{% endif %}) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja index 5394ea2355..faa469594b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja @@ -160,7 +160,9 @@ void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) { {% if ExtendReflectionSerialize is defined %} auto {{preSerialize}} = {% else %} {% endif %}serializeContext->Class<{{ attribute_Name }}{% if attribute_Base is defined %}, {{ attribute_Base }}{% endif %}>(){{postSerialize}} {% if attribute_EventHandler is defined %} +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// {{preSerialize}}->EventHandler<{{ attribute_EventHandler }}>(){{postSerialize}} +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) {% endif %} {# Serialized Properties #} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index c36110ef92..e1af284e00 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -2056,11 +2056,6 @@ namespace ScriptCanvas } } - void Datum::OnReadBegin() - { - OnSerializeBegin(); - } - void Datum::OnDeserialize() { if (m_type.GetType() == Data::eType::BehaviorContextObject) @@ -2084,10 +2079,17 @@ namespace ScriptCanvas } } +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// + void Datum::OnReadBegin() + { + OnSerializeBegin(); + } + void Datum::OnWriteEnd() { OnSerializeEnd(); } +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) void Datum::Reflect(AZ::ReflectContext* reflection) { @@ -2095,7 +2097,9 @@ namespace ScriptCanvas { serializeContext->Class() ->Version(DatumHelpers::Version::Current, &DatumHelpers::VersionConverter) +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) ->Field("m_isUntypedStorage", &Datum::m_isOverloadedStorage) ->Field("m_type", &Datum::m_type) ->Field("m_originality", &Datum::m_originality) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index 3ad09e2297..df94c32559 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -236,6 +236,7 @@ namespace ScriptCanvas } }; +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler { public: @@ -253,6 +254,7 @@ namespace ScriptCanvas datum->OnWriteEnd(); } }; +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) friend class SerializeContextEventHandler; @@ -353,10 +355,12 @@ namespace ScriptCanvas void OnSerializeBegin() override; void OnDeserialize() override; - + +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void OnReadBegin(); void OnWriteEnd(); +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) AZ_INLINE bool SatisfiesTraits(AZ::u8 behaviorValueTraits) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp index d8fd409147..77de1330e2 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/GraphData.cpp @@ -19,6 +19,7 @@ namespace AZ namespace ScriptCanvas { +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// class GraphDataEventHandler : public AZ::SerializeContext::IEventHandler { public: @@ -28,6 +29,7 @@ namespace ScriptCanvas reinterpret_cast(classPtr)->OnDeserialized(); } }; +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) void GraphData::Reflect(AZ::ReflectContext* context) { @@ -40,7 +42,9 @@ namespace ScriptCanvas serializeContext->Class() ->Version(4, &GraphData::VersionConverter) +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) ->Field("m_nodes", &GraphData::m_nodes) ->Field("m_connections", &GraphData::m_connections) ->Field("m_dependentAssets", &GraphData::m_dependentAssets) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 5af59fc166..6173ccfb4f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -60,6 +60,7 @@ namespace ScriptCanvas // Node ///////// +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// class NodeEventHandler : public AZ::SerializeContext::IEventHandler { @@ -70,6 +71,7 @@ namespace ScriptCanvas node->OnDeserialize(); } }; +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) bool NodeVersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& nodeElementNode) { @@ -420,7 +422,9 @@ namespace ScriptCanvas serializeContext->RegisterGenericType>(); serializeContext->Class() +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) ->Version(NodeCpp::Version::Current, &NodeVersionConverter) ->Field("Slots", &Node::m_slots) ->Field("Datums", &Node::m_slotDatums) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index 298eff5222..27f0b3862d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -63,6 +63,7 @@ namespace ScriptCanvas struct BehaviorContextMethodHelper; +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// template class SerializeContextReadWriteHandler : public AZ::SerializeContext::IEventHandler { @@ -126,6 +127,7 @@ namespace ScriptCanvas deserializedObject->OnWriteEnd(); } }; +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) // List of slots that will be create visual only slots on the nodes. // Useful for special configurations or editor only concepts. diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp index bfcb629225..938c7c3e70 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp @@ -614,10 +614,12 @@ namespace ScriptCanvas Node::OnDeserialize(); } +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void EBusEventHandler::OnWriteEnd() { OnDeserialize(); } +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) NodeTypeIdentifier EBusEventHandler::GetOutputNodeType(const SlotId& slotId) const { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h index b36636fe1c..c6d4a8b512 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h @@ -140,7 +140,9 @@ namespace ScriptCanvas void OnDeserialize(); +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void OnWriteEnd(); +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) AZStd::string GetNodeName() const override { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 5a732a1185..dbf2d47417 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -771,10 +771,12 @@ namespace ScriptCanvas Node::OnDeserialize(); } +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void Method::OnWriteEnd() { OnDeserialize(); } +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) bool Method::BranchesOnResult() const { @@ -838,7 +840,9 @@ namespace ScriptCanvas { serializeContext->Class() ->Version(MethodCPP::eVersion::Current, &MethodCPP::MethodVersionConverter) +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler>() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) ->Field("methodType", &Method::m_methodType) ->Field("methodName", &Method::m_lookupName) ->Field("className", &Method::m_className) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index b44539d915..5584212048 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -109,7 +109,9 @@ namespace ScriptCanvas void OnDeserialize(); +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void OnWriteEnd(); +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) virtual bool IsMethodOverloaded() const { return false; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp index f20f79a6b1..29f583a4d9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp @@ -60,7 +60,9 @@ namespace ScriptCanvas { serializeContext->Class() ->Version(MethodOverloadedCpp::Version::Current, &MethodOverloadedVersionConverter) +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// ->EventHandler>() +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) ->Field("orderedInputSlotIds", &MethodOverloaded::m_orderedInputSlotIds) ->Field("outputSlotIds", &MethodOverloaded::m_outputSlotIds) ; @@ -397,6 +399,7 @@ namespace ScriptCanvas return signature; } +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// void MethodOverloaded::OnWriteBegin() { } @@ -405,6 +408,7 @@ namespace ScriptCanvas { OnDeserialize(); } +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) void MethodOverloaded::OnDeserialize() { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h index a4d7ea83d8..5c92bf1841 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h @@ -33,7 +33,9 @@ namespace ScriptCanvas , public OverloadContractInterface { private: +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// friend class SerializeContextReadWriteHandler; +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) public: static void Reflect(AZ::ReflectContext* reflectContext); @@ -91,12 +93,14 @@ namespace ScriptCanvas // \todo make execution thread sensitive, which can then support generic programming Grammar::FunctionPrototype GetInputSignature() const; +#if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// // SerializeContextReadWriteHandler void OnReadBegin() {} void OnReadEnd() {} void OnWriteBegin(); void OnWriteEnd(); +#endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) void OnDeserialize() override; From 1d1cea34dda837e69f0dbea11b578084297bc4c0 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 18 Aug 2021 11:58:24 -0700 Subject: [PATCH 08/27] Undo artifacts for JsonUtils sojourn into AzToolsFramework Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h | 2 -- Gems/Atom/Feature/Common/Code/CMakeLists.txt | 4 ---- Gems/Atom/RPI/Code/CMakeLists.txt | 3 --- 3 files changed, 9 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h index 62020d81d0..c7777feec0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h @@ -15,8 +15,6 @@ #include #include -// hello? - namespace AZ { namespace IO diff --git a/Gems/Atom/Feature/Common/Code/CMakeLists.txt b/Gems/Atom/Feature/Common/Code/CMakeLists.txt index 8a9fe3b07c..8ed02f2c2f 100644 --- a/Gems/Atom/Feature/Common/Code/CMakeLists.txt +++ b/Gems/Atom/Feature/Common/Code/CMakeLists.txt @@ -34,7 +34,6 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework PUBLIC Gem::Atom_RPI.Public Gem::Atom_Utils.Static @@ -63,7 +62,6 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework PUBLIC Gem::Atom_RPI.Public Gem::Atom_Utils.Static @@ -87,7 +85,6 @@ ly_add_target( PRIVATE AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework Gem::Atom_Feature_Common.Static Gem::Atom_Feature_Common.Public 3rdParty::lux_core @@ -164,7 +161,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) BUILD_DEPENDENCIES PRIVATE AZ::AzFramework - AZ::AzToolsFramework AZ::AzTest Gem::Atom_Feature_Common.Static Gem::Atom_Feature_Common.Public diff --git a/Gems/Atom/RPI/Code/CMakeLists.txt b/Gems/Atom/RPI/Code/CMakeLists.txt index 54e74b756b..521178be20 100644 --- a/Gems/Atom/RPI/Code/CMakeLists.txt +++ b/Gems/Atom/RPI/Code/CMakeLists.txt @@ -40,7 +40,6 @@ ly_add_target( AZ::AtomCore AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework PUBLIC Gem::Atom_RHI.Public ) @@ -63,7 +62,6 @@ ly_add_target( AZ::AtomCore AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework Gem::Atom_RPI.Public Gem::Atom_RHI.Public Gem::Atom_RHI.Reflect @@ -109,7 +107,6 @@ if(PAL_TRAIT_BUILD_HOST_TOOLS) AZ::AtomCore AZ::AzCore AZ::AzFramework - AZ::AzToolsFramework Gem::Atom_RPI.Public Gem::Atom_RHI.Public ) From ca8a148b63e49b0e5350bfa75ba535683a199247 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 18 Aug 2021 12:16:39 -0700 Subject: [PATCH 09/27] fix Linux compile error Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Include/ScriptCanvas/Core/SerializationListener.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h index d53e66f21b..90d8814d16 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h @@ -14,7 +14,7 @@ namespace ScriptCanvas { public: AZ_RTTI(SerializationListener, "{CA4EE281-30B3-4928-BCD8-9305CE75E463}"); - virtual ~SerializationListener() = 0 {} + virtual ~SerializationListener() {} virtual void OnSerializeBegin() {} virtual void OnSerializeEnd() {} From c701522adcff26931021741702458eb4998232d8 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 18 Aug 2021 13:28:01 -0700 Subject: [PATCH 10/27] update error messaging, remove unnecessary comments Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/AzCore/Serialization/Json/JsonUtils.cpp | 7 ++++++- .../Code/Editor/Assets/ScriptCanvasAsset.cpp | 4 ++-- .../Code/Editor/Assets/ScriptCanvasAssetHandler.cpp | 11 ++++++++--- .../ScriptCanvas/Libraries/Core/EBusEventHandler.cpp | 1 - .../Include/ScriptCanvas/Libraries/Core/Method.cpp | 1 - .../ScriptCanvas/Libraries/Core/MethodOverloaded.cpp | 2 -- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp index 49a902de54..98162ea594 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp @@ -333,7 +333,12 @@ namespace AZ // validate class name auto classData = loadSettings.m_serializeContext->FindClassData(classId); - if (!classData || azstricmp(classData->m_name, className) != 0) + if (!classData) + { + return AZ::Failure(AZStd::string::format("Try to load class from Id %s", classId.ToString().c_str())); + } + + if (azstricmp(classData->m_name, className) != 0) { return AZ::Failure(AZStd::string::format("Try to load class %s from class %s data", classData->m_name, className)); } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp index 8d9f575586..18736db12c 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAsset.cpp @@ -114,13 +114,13 @@ namespace ScriptCanvasEditor ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() { - AZ_Assert(m_data != nullptr, "data not initialized"); + AZ_Assert(m_data != nullptr, "ScriptCanvasData not initialized, it must be created on construction"); return *m_data; } const ScriptCanvas::ScriptCanvasData& ScriptCanvasAsset::GetScriptCanvasData() const { - AZ_Assert(m_data != nullptr, "data not initialized"); + AZ_Assert(m_data != nullptr, "ScriptCanvasData not initialized, it must be created on construction"); return *m_data; } } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 7a07902a11..9094c135bd 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -98,7 +98,6 @@ namespace ScriptCanvasEditor { byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); AZ::JsonDeserializerSettings settings; - // \todo more mapping stuff needs to go in the settings settings.m_serializeContext = m_serializeContext; // attempt JSON deserialization... if (JSRU::LoadObjectFromStreamByType @@ -139,7 +138,10 @@ namespace ScriptCanvasEditor return SaveAssetData(assetData, stream, AZ::DataStream::ST_XML); } - bool ScriptCanvasAssetHandler::SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, [[maybe_unused]] AZ::DataStream::StreamType streamType) + bool ScriptCanvasAssetHandler::SaveAssetData + ( const ScriptCanvasAsset* assetData + , AZ::IO::GenericStream* stream + , [[maybe_unused]] AZ::DataStream::StreamType streamType) { namespace JSRU = AZ::JsonSerializationUtils; using namespace ScriptCanvas; @@ -153,6 +155,8 @@ namespace ScriptCanvasEditor } else { + AZ_Error("ScriptCanvas", false, "Saving ScriptCavas assets in the handler requires a valid IO stream, " + "asset pointer, and serialize context"); return false; } } @@ -177,7 +181,8 @@ namespace ScriptCanvasEditor EBUS_EVENT_RESULT(m_serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); if (!m_serializeContext) { - AZ_Error("Script Canvas", false, "ScriptCanvasAssetHandler: No serialize context provided! We will not be able to process Graph Asset type"); + AZ_Error("Script Canvas", false, "ScriptCanvasAssetHandler: No serialize context provided! " + "We will not be able to process Graph Asset type"); } } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp index 938c7c3e70..ef73bb967d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp @@ -610,7 +610,6 @@ namespace ScriptCanvas CreateHandler(m_ebusName); } - /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super Node::OnDeserialize(); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index dbf2d47417..eb1ee501a9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -767,7 +767,6 @@ namespace ScriptCanvas m_resultSlotIDs.emplace_back(SlotId{}); } - /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super Node::OnDeserialize(); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp index 29f583a4d9..6de72af292 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp @@ -462,8 +462,6 @@ namespace ScriptCanvas } SetWarnOnMissingFunction(true); - - /// \note Call super() anti-pattern https://en.wikipedia.org/wiki/Call_super Node::OnDeserialize(); } From a68f5c53c9dcd69462ab07b905ee90beee2699b1 Mon Sep 17 00:00:00 2001 From: evanchia Date: Thu, 19 Aug 2021 17:54:48 -0700 Subject: [PATCH 11/27] Adds a verification response for the remote console connecting Signed-off-by: evanchia --- Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp | 8 ++++++++ Code/Tools/RemoteConsole/Core/RemoteConsoleCore.h | 1 + .../ly_remote_console/remote_console_commands.py | 12 +++--------- .../tests/unit/test_remote_console_commands.py | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp index a4e7bd24fa..d0e9e6a760 100644 --- a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp +++ b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.cpp @@ -383,6 +383,13 @@ void SRemoteClient::Run() bool ok = true; bool autoCompleteDoneSent = false; + + // Send a message that is used to verify that the Remote Console connected + SNoDataEvent connectMessage; + SRemoteEventFactory::GetInst()->WriteToBuffer(&connectMessage, szBuff, size, kDefaultBufferSize); + ok &= SendPackage(szBuff, size); + ok &= RecvPackage(szBuff, size); + ok &= m_pServer->ReadBuffer(szBuff, size); while (ok) { // read data @@ -531,6 +538,7 @@ SRemoteEventFactory::SRemoteEventFactory() REGISTER_EVENT_NODATA(eCET_Strobo_FrameInfoStart); REGISTER_EVENT_STRING(eCET_Strobo_FrameInfoAdd); + REGISTER_EVENT_NODATA(eCET_ConnectMessage); } ///////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.h b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.h index 7e22be5735..d9a6f7aba6 100644 --- a/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.h +++ b/Code/Tools/RemoteConsole/Core/RemoteConsoleCore.h @@ -60,6 +60,7 @@ enum EConsoleEventType eCET_Strobo_FrameInfoStart, eCET_Strobo_FrameInfoAdd, + eCET_ConnectMessage, }; struct SRemoteEventFactory; diff --git a/Tools/RemoteConsole/ly_remote_console/ly_remote_console/remote_console_commands.py b/Tools/RemoteConsole/ly_remote_console/ly_remote_console/remote_console_commands.py index 872537bdca..559823c820 100755 --- a/Tools/RemoteConsole/ly_remote_console/ly_remote_console/remote_console_commands.py +++ b/Tools/RemoteConsole/ly_remote_console/ly_remote_console/remote_console_commands.py @@ -27,7 +27,8 @@ CONSOLE_MESSAGE_MAP = { 'COMMAND': BASE_MSG_TYPE + 5, 'AUTOCOMPLETELIST': BASE_MSG_TYPE + 6, 'AUTOCOMPLETELISTDONE': BASE_MSG_TYPE + 7, - 'GAMEPLAYEVENT': BASE_MSG_TYPE + 22 + 'GAMEPLAYEVENT': BASE_MSG_TYPE + 22, + 'CONNECTMESSAGE': BASE_MSG_TYPE + 25, } @@ -295,14 +296,7 @@ class RemoteConsole: self.handlers[key].set() continue - # The very first connection using the socket will return all of the auto complete items, turned off so no one - # wouldn't need to see them - elif message_type == CONSOLE_MESSAGE_MAP['AUTOCOMPLETELIST']: - pass - - # The after the autocompletelists finishes we will be ready to send console commands we determine that by - # looking at for an autocompletelistdone message - elif message_type == CONSOLE_MESSAGE_MAP['AUTOCOMPLETELISTDONE']: + elif message_type == CONSOLE_MESSAGE_MAP['CONNECTMESSAGE']: self.ready.set() # cleanup expect_log_line handers if the matching string was found or timeout happened. diff --git a/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py b/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py index 51a85f0413..e0ac82eb99 100755 --- a/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py +++ b/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py @@ -141,11 +141,11 @@ class TestRemoteConsole(): @mock.patch('socket.socket', mock.MagicMock()) @mock.patch('ly_remote_console.remote_console_commands.threading', mock.MagicMock()) - def test_HandleMessage_AutoCompleteListDone_ReadySet(self): + def test_HandleMessage_ConnectMessage_ReadySet(self): rc_instance = remote_console.RemoteConsole() rc_instance.on_display = mock.MagicMock() rc_instance.ready = mock.MagicMock() - msg = b'70' # in python3 socket.recv returns byte array. 7 is AUTOCOMPLETELISTDONE + msg = b'I0' # in python3 socket.recv returns byte array. 7 is AUTOCOMPLETELISTDONE rc_instance._handle_message(msg) From d7d2e84feee81bc5e8bd9694c5fe15f86980fcf2 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Fri, 20 Aug 2021 19:35:38 -0700 Subject: [PATCH 12/27] Added all the missing serializer support, fixed up serialization notification Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AtomCore/Tests/atomcore_tests_files.cmake | 1 - .../Serialization/AZStdAnyDataContainer.inl | 44 +- .../Serialization/Json/BaseJsonSerializer.cpp | 4 +- .../Serialization/Json/BaseJsonSerializer.h | 14 +- .../Serialization/Json/JsonDeserializer.cpp | 4 +- .../AzCore/Serialization/Json/JsonUtils.cpp | 2 +- .../Json}/JsonSerializationUtilsTests.cpp | 0 .../AzCore/Tests/azcoretests_files.cmake | 1 + .../Tests/Material/MaterialFunctorTests.cpp | 1 - .../ExpressionEngine/ExpressionTree.h | 31 +- .../Source/ElementInformationSerializer.inl | 165 + .../ExpressionEvaluationSystemComponent.cpp | 15 +- .../ExpressionPrimitivesSerializers.inl | 147 + .../Code/expressionevaluation_files.cmake | 2 + .../Assets/ScriptCanvasAssetHandler.cpp | 82 +- .../AutoGen/ScriptCanvasGrammar_Header.jinja | 16 +- .../AutoGen/ScriptCanvasGrammar_Source.jinja | 19 +- .../AutoGen/ScriptCanvas_Macros.jinja | 20 +- .../Code/Include/ScriptCanvas/Core/Datum.cpp | 22 +- .../Code/Include/ScriptCanvas/Core/Datum.h | 11 - .../ScriptCanvas/Core/SerializationListener.h | 3 +- .../Data/BehaviorContextObject.cpp | 14 +- .../ScriptCanvas/Data/BehaviorContextObject.h | 14 +- .../Libraries/Core/MethodOverloaded.cpp | 5 +- .../Libraries/Core/MethodOverloaded.h | 3 +- .../BehaviorContextObjectSerializer.cpp | 149 + ...er.h => BehaviorContextObjectSerializer.h} | 4 +- .../Serialization/DatumSerializer.cpp | 69 +- .../Serialization/GraphDataSerializer.cpp | 100 - .../Code/Source/SystemComponent.cpp | 4 +- .../Code/scriptcanvasgem_common_files.cmake | 4 +- ...est_PathologicalFlowOfControl.scriptcanvas | 18342 ++++++---------- 32 files changed, 7726 insertions(+), 11586 deletions(-) rename Code/Framework/{AtomCore/Tests => AzCore/Tests/Serialization/Json}/JsonSerializationUtilsTests.cpp (100%) create mode 100644 Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl create mode 100644 Gems/ExpressionEvaluation/Code/Source/ExpressionPrimitivesSerializers.inl create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp rename Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/{GraphDataSerializer.h => BehaviorContextObjectSerializer.h} (86%) delete mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp diff --git a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake index f2c0c5c051..0f5fcb441d 100644 --- a/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake +++ b/Code/Framework/AtomCore/Tests/atomcore_tests_files.cmake @@ -10,7 +10,6 @@ set(FILES ArrayView.cpp ConcurrencyCheckerTests.cpp InstanceDatabase.cpp - JsonSerializationUtilsTests.cpp lru_cache.cpp Main.cpp vector_set.cpp diff --git a/Code/Framework/AzCore/AzCore/Serialization/AZStdAnyDataContainer.inl b/Code/Framework/AzCore/AzCore/Serialization/AZStdAnyDataContainer.inl index 0e9306a481..f0694ed2b3 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/AZStdAnyDataContainer.inl +++ b/Code/Framework/AzCore/AzCore/Serialization/AZStdAnyDataContainer.inl @@ -209,39 +209,35 @@ namespace AZ //! performance sensitive code. AZ_INLINE bool CompareAnyValue(const AZStd::any& lhs, const AZStd::any& rhs) { - bool isEqual = false; - - if (lhs.type() != rhs.type()) + if (lhs.type() == rhs.type()) { - return false; - } + AZ::SerializeContext* serializeContext = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); - AZ::SerializeContext* serializeContext = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationRequests::GetSerializeContext); - - const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(lhs.type()); - if (classData) - { - if (classData->m_serializer) + const AZ::SerializeContext::ClassData* classData = serializeContext->FindClassData(lhs.type()); + if (classData) { - isEqual = classData->m_serializer->CompareValueData(AZStd::any_cast(&lhs), AZStd::any_cast(&rhs)); - } - else - { - AZStd::vector myData; - AZ::IO::ByteContainerStream myDataStream(&myData); + if (classData->m_serializer) + { + return classData->m_serializer->CompareValueData(AZStd::any_cast(&lhs), AZStd::any_cast(&rhs)); + } + else + { + AZStd::vector myData; + AZ::IO::ByteContainerStream myDataStream(&myData); - AZ::Utils::SaveObjectToStream(myDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast(&lhs), lhs.type()); + AZ::Utils::SaveObjectToStream(myDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast(&lhs), lhs.type()); - AZStd::vector otherData; - AZ::IO::ByteContainerStream otherDataStream(&otherData); + AZStd::vector otherData; + AZ::IO::ByteContainerStream otherDataStream(&otherData); - AZ::Utils::SaveObjectToStream(otherDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast(&rhs), rhs.type()); - isEqual = (myData.size() == otherData.size()) && (memcmp(myData.data(), otherData.data(), myData.size()) == 0); + AZ::Utils::SaveObjectToStream(otherDataStream, AZ::ObjectStream::ST_BINARY, AZStd::any_cast(&rhs), rhs.type()); + return (myData.size() == otherData.size()) && (memcmp(myData.data(), otherData.data(), myData.size()) == 0); + } } } - return isEqual; + return false; } } } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp index 4a02563f3a..7309955a1c 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.cpp @@ -213,7 +213,7 @@ namespace AZ void* object, const Uuid& typeId, const rapidjson::Value& value, JsonDeserializerContext& context, ContinuationFlags flags) { bool loadAsNewInstance = (flags & ContinuationFlags::LoadAsNewInstance) == ContinuationFlags::LoadAsNewInstance; - JsonDeserializer::UseTypeDeserializer useCustom = (flags & ContinuationFlags::NoTypeSerializer) == ContinuationFlags::NoTypeSerializer + JsonDeserializer::UseTypeDeserializer useCustom = (flags & ContinuationFlags::IgnoreTypeSerializer) == ContinuationFlags::IgnoreTypeSerializer ? JsonDeserializer::UseTypeDeserializer::No : JsonDeserializer::UseTypeDeserializer::Yes; @@ -228,7 +228,7 @@ namespace AZ { using namespace JsonSerializationResult; - JsonSerializer::UseTypeSerializer useCustom = (flags & ContinuationFlags::NoTypeSerializer) == ContinuationFlags::NoTypeSerializer + JsonSerializer::UseTypeSerializer useCustom = (flags & ContinuationFlags::IgnoreTypeSerializer) == ContinuationFlags::IgnoreTypeSerializer ? JsonSerializer::UseTypeSerializer::No : JsonSerializer::UseTypeSerializer::Yes; diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h index 12ae01799c..7d2af01c16 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/BaseJsonSerializer.h @@ -159,13 +159,13 @@ namespace AZ enum class ContinuationFlags { - None = 0, //! No extra flags. - ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance. - ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one. - LoadAsNewInstance = 1 << 2, //! Treats the value as if it's a newly created instance. This may trigger serializers marked with - //! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to - //! an array. - NoTypeSerializer = 1 << 3, //! Ignore the custom/specific serializer for the TypeId + None = 0, //! No extra flags. + ResolvePointer = 1 << 0, //! The pointer passed in contains a pointer. The (de)serializer will attempt to resolve to an instance. + ReplaceDefault = 1 << 1, //! The default value provided for storing will be replaced with a newly created one. + LoadAsNewInstance = 1 << 2, //! Treats the value as if it's a newly created instance. This may trigger serializers marked with + //! OperationFlags::InitializeNewInstance. Used for instance by pointers or new instances added to + //! an array. + IgnoreTypeSerializer = 1 << 3, //! Ignore the custom/specific serializer for the TypeId }; enum class OperationFlags diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index dcc0550107..ae47c1c585 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -73,7 +73,9 @@ namespace AZ } if (BaseJsonSerializer* serializer - = context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId())) + = (custom == UseTypeDeserializer::Yes) + ? context.GetRegistrationContext()->GetSerializerForType(classData->m_azRtti->GetGenericTypeId()) + : nullptr) { return DeserializerDefaultCheck(serializer, object, typeId, value, isNewInstance, context); } diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp index 98162ea594..d04c23f536 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp @@ -22,7 +22,7 @@ #include #include -#include "JsonUtils.h" +#include namespace AZ { diff --git a/Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp b/Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializationUtilsTests.cpp similarity index 100% rename from Code/Framework/AtomCore/Tests/JsonSerializationUtilsTests.cpp rename to Code/Framework/AzCore/Tests/Serialization/Json/JsonSerializationUtilsTests.cpp diff --git a/Code/Framework/AzCore/Tests/azcoretests_files.cmake b/Code/Framework/AzCore/Tests/azcoretests_files.cmake index ca0e2862fc..d3f6663489 100644 --- a/Code/Framework/AzCore/Tests/azcoretests_files.cmake +++ b/Code/Framework/AzCore/Tests/azcoretests_files.cmake @@ -105,6 +105,7 @@ set(FILES Serialization/Json/JsonSerializationResultTests.cpp Serialization/Json/JsonSerializationTests.h Serialization/Json/JsonSerializationTests.cpp + Serialization/Json/JsonSerializationUtilsTests.cpp Serialization/Json/JsonSerializerConformityTests.h Serialization/Json/JsonSerializerMock.h Serialization/Json/MapSerializerTests.cpp diff --git a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp index ca41bbac40..0c84484508 100644 --- a/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp +++ b/Gems/Atom/RPI/Code/Tests/Material/MaterialFunctorTests.cpp @@ -19,7 +19,6 @@ #include #include -//#include namespace UnitTest { using namespace AZ; diff --git a/Gems/ExpressionEvaluation/Code/Include/ExpressionEvaluation/ExpressionEngine/ExpressionTree.h b/Gems/ExpressionEvaluation/Code/Include/ExpressionEvaluation/ExpressionEngine/ExpressionTree.h index e9da3bbfba..e47e1e84c6 100644 --- a/Gems/ExpressionEvaluation/Code/Include/ExpressionEvaluation/ExpressionEngine/ExpressionTree.h +++ b/Gems/ExpressionEvaluation/Code/Include/ExpressionEvaluation/ExpressionEngine/ExpressionTree.h @@ -11,6 +11,11 @@ #include +namespace AZ +{ + class ExpressionTreeVariableDescriptorSerializer; +} + namespace ExpressionEvaluation { // Holds all of the tokeniszed information from parsing an expression string. @@ -20,8 +25,22 @@ namespace ExpressionEvaluation { // Friend class for reflection friend class ExpressionEvaluationSystemComponent; + friend class ExpressionTreeVariableDescriptorSerializer; public: + struct VariableDescriptor + { + AZ_TYPE_INFO(VariableDescriptor, "{5E1A0044-E0E7-46D3-8BC6-A22E226ADB83}"); + + VariableDescriptor() + { + m_supportedTypes.push_back(azrtti_typeid()); + } + + AZStd::vector< AZ::Uuid > m_supportedTypes; + ExpressionVariable m_value; + }; + AZ_RTTI(ExpressionTree, "{4CCF3DFD-2EA8-47CB-AF25-353BC034EF42}"); AZ_CLASS_ALLOCATOR(ExpressionTree, AZ::SystemAllocator, 0); @@ -147,18 +166,6 @@ namespace ExpressionEvaluation private: - struct VariableDescriptor - { - AZ_TYPE_INFO(VariableDescriptor, "{5E1A0044-E0E7-46D3-8BC6-A22E226ADB83}"); - - VariableDescriptor() - { - m_supportedTypes.push_back(azrtti_typeid()); - } - - AZStd::vector< AZ::Uuid > m_supportedTypes; - ExpressionVariable m_value; - }; AZStd::unordered_map< AZ::Crc32, VariableDescriptor > m_variables; diff --git a/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl b/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl new file mode 100644 index 0000000000..19d220a4f3 --- /dev/null +++ b/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl @@ -0,0 +1,165 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace AZ +{ + class ElementInformationSerializer + : public BaseJsonSerializer + { + + public: + AZ_RTTI(ElementInformationSerializer, "{B33E6AA9-C700-4E3D-857C-55F362AFE57A}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + + private: + using ElementInformation = ExpressionEvaluation::ElementInformation; + + JsonSerializationResult::Result Load + ( void* outputValue + , const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) override + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "ElementInformationSerializer Load against " + "output typeID that was not ElementInformation"); + AZ_Assert(outputValue, "ElementInformationSerializer Load against null output"); + + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + auto outputDatum = reinterpret_cast(outputValue); + result.Combine(ContinueLoadingFromJsonObjectField + ( &outputDatum->m_id + , azrtti_typeidm_id)>() + , inputValue + , "Id" + , context)); + + // any storage begin + auto isEmptyAny = inputValue.FindMember("isEmptyAny"); + if (isEmptyAny == inputValue.MemberEnd()) + { + return context.Report + (JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , "ElementInformationSerializer::Load failed to load the 'isEmptyAny'' member"); + } + + if (!isEmptyAny->value.GetBool()) + { + AZ::Uuid typeId = AZ::Uuid::CreateNull(); + auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); + if (typeIdMember == inputValue.MemberEnd()) + { + return context.Report + (JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , AZStd::string::format("ElementInformationSerializer::Load failed to load the %s member" + , JsonSerialization::TypeIdFieldIdentifier)); + } + + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic + , "ElementInformationSerializer::Load failed to load the AZ TypeId of the value"); + } + + AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "ElementInformationSerializer::Load failed to load a value matched the " + "reported AZ TypeId. The C++ declaration may have been deleted or changed."); + } + + result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "Value", context)); + outputDatum->m_extraStore = storage; + } + // any storage end + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ElementInformationSerializer Load finished loading ElementInformation" + : "ElementInformationSerializer Load failed to load ElementInformation"); + } + + JsonSerializationResult::Result Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , const Uuid& valueTypeId, JsonSerializerContext& context) override + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid(), "ElementInformation Store against value typeID that " + "was not ElementInformation"); + AZ_Assert(inputValue, "ElementInformation Store against null inputValue pointer "); + + auto inputScriptDataPtr = reinterpret_cast(inputValue); + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + + if (defaultScriptDataPtr) + { + if (inputScriptDataPtr->m_id == defaultScriptDataPtr->m_id + && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_extraStore, defaultScriptDataPtr->m_extraStore)) + { + return context.Report + ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ElementInformation Store used defaults for " + "ElementInformation"); + } + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + outputValue.SetObject(); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "Id" + , &inputScriptDataPtr->m_id + , defaultScriptDataPtr ? &defaultScriptDataPtr->m_id : nullptr + , azrtti_typeidm_id)>() + , context)); + + + outputValue.AddMember("isEmptyAny", rapidjson::Value(inputScriptDataPtr->m_extraStore.empty()), context.GetJsonAllocator()); + + if (!inputScriptDataPtr->m_extraStore.empty()) + { + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_extraStore.type(), context)); + outputValue.AddMember + (rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(typeValue) + , context.GetJsonAllocator()); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "Value" + , AZStd::any_cast(const_cast(&inputScriptDataPtr->m_extraStore)) + , defaultScriptDataPtr ? AZStd::any_cast(const_cast(&defaultScriptDataPtr->m_extraStore)) : nullptr + , inputScriptDataPtr->m_extraStore.type() + , context)); + + } + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ElementInformation Store finished saving ElementInformation" + : "ElementInformation Store failed to save ElementInformation"); + } + }; + + AZ_CLASS_ALLOCATOR_IMPL(ElementInformationSerializer, SystemAllocator, 0); +} diff --git a/Gems/ExpressionEvaluation/Code/Source/ExpressionEvaluationSystemComponent.cpp b/Gems/ExpressionEvaluation/Code/Source/ExpressionEvaluationSystemComponent.cpp index 42ac124e6e..9a6848712a 100644 --- a/Gems/ExpressionEvaluation/Code/Source/ExpressionEvaluationSystemComponent.cpp +++ b/Gems/ExpressionEvaluation/Code/Source/ExpressionEvaluationSystemComponent.cpp @@ -6,15 +6,16 @@ * */ -#include - -#include #include #include - +#include +#include #include #include #include +#include +#include +#include namespace ExpressionEvaluation { @@ -145,6 +146,12 @@ namespace ExpressionEvaluation ; } } + + if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context)) + { + jsonContext->Serializer()->HandlesType(); + jsonContext->Serializer()->HandlesType(); + } } void ExpressionEvaluationSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Gems/ExpressionEvaluation/Code/Source/ExpressionPrimitivesSerializers.inl b/Gems/ExpressionEvaluation/Code/Source/ExpressionPrimitivesSerializers.inl new file mode 100644 index 0000000000..76f43a9b82 --- /dev/null +++ b/Gems/ExpressionEvaluation/Code/Source/ExpressionPrimitivesSerializers.inl @@ -0,0 +1,147 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace AZ +{ + class ExpressionTreeVariableDescriptorSerializer + : public BaseJsonSerializer + { + + public: + AZ_RTTI(ExpressionTreeVariableDescriptorSerializer, "{5EFF37D6-BD54-45C6-9FC6-B1E0D3A8204C}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + + private: + using VariableDescriptor = ExpressionEvaluation::ExpressionTree::VariableDescriptor; + + JsonSerializationResult::Result Load + ( void* outputValue + , const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) override + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "ExpressionTreeVariableDescriptorSerializer Load against " + "output typeID that was not VariableDescriptor"); + AZ_Assert(outputValue, "ExpressionTreeVariableDescriptorSerializer Load against null output"); + + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + auto outputDatum = reinterpret_cast(outputValue); + + result.Combine(ContinueLoadingFromJsonObjectField + ( &outputDatum->m_supportedTypes + , azrtti_typeidm_supportedTypes)>() + , inputValue + , "SupportedTypes" + , context)); + + // any storage begin + AZ::Uuid typeId = AZ::Uuid::CreateNull(); + auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); + if (typeIdMember == inputValue.MemberEnd()) + { + return context.Report + ( JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , AZStd::string::format("ExpressionTreeVariableDescriptorSerializer::Load failed to load the %s member" + , JsonSerialization::TypeIdFieldIdentifier)); + } + + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic + , "ExpressionTreeVariableDescriptorSerializer::Load failed to load the AZ TypeId of the value"); + } + + AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "ExpressionTreeVariableDescriptorSerializer::Load failed to load a value matched the " + "reported AZ TypeId. The C++ declaration may have been deleted or changed."); + } + + result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "Value", context)); + outputDatum->m_value = storage; + // any storage end + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ExpressionTreeVariableDescriptorSerializer Load finished loading VariableDescriptor" + : "ExpressionTreeVariableDescriptorSerializer Load failed to load VariableDescriptor"); + } + + JsonSerializationResult::Result Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , const Uuid& valueTypeId, JsonSerializerContext& context) override + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid(), "VariableDescriptor Store against value typeID that " + "was not VariableDescriptor"); + AZ_Assert(inputValue, "VariableDescriptor Store against null inputValue pointer "); + + auto inputScriptDataPtr = reinterpret_cast(inputValue); + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + + if (defaultScriptDataPtr) + { + if (inputScriptDataPtr->m_supportedTypes == defaultScriptDataPtr->m_supportedTypes + && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_value, defaultScriptDataPtr->m_value)) + { + return context.Report + ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "VariableDescriptor Store used defaults for " + "VariableDescriptor"); + } + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + outputValue.SetObject(); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "SupportedTypes" + , &inputScriptDataPtr->m_supportedTypes + , defaultScriptDataPtr ? &defaultScriptDataPtr->m_supportedTypes : nullptr + , azrtti_typeidm_supportedTypes)>() + , context)); + + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_value.type(), context)); + outputValue.AddMember + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(typeValue) + , context.GetJsonAllocator()); + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "Value" + , AZStd::any_cast(const_cast(&inputScriptDataPtr->m_value)) + , defaultScriptDataPtr ? AZStd::any_cast(const_cast(&defaultScriptDataPtr->m_value)) : nullptr + , inputScriptDataPtr->m_value.type() + , context)); + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "VariableDescriptor Store finished saving VariableDescriptor" + : "VariableDescriptor Store failed to save VariableDescriptor"); + } + }; + + AZ_CLASS_ALLOCATOR_IMPL(ExpressionTreeVariableDescriptorSerializer, SystemAllocator, 0); +} diff --git a/Gems/ExpressionEvaluation/Code/expressionevaluation_files.cmake b/Gems/ExpressionEvaluation/Code/expressionevaluation_files.cmake index 00d546459a..908622c163 100644 --- a/Gems/ExpressionEvaluation/Code/expressionevaluation_files.cmake +++ b/Gems/ExpressionEvaluation/Code/expressionevaluation_files.cmake @@ -13,6 +13,8 @@ set(FILES Include/ExpressionEvaluation/ExpressionEngine/ExpressionTypes.h Source/ExpressionEvaluationSystemComponent.cpp Source/ExpressionEvaluationSystemComponent.h + Source/ExpressionPrimitivesSerializers.inl + Source/ElementInformationSerializer.inl Source/ExpressionEngine/ExpressionElementParser.h Source/ExpressionEngine/ExpressionPrimitive.cpp Source/ExpressionEngine/ExpressionPrimitive.h diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 9094c135bd..6f86b93dda 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -12,12 +12,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -27,6 +27,26 @@ #include #include #include +#include + +namespace ScriptCanvasAssetHandlerCpp +{ + using namespace ScriptCanvas; + + void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners) + { + for (auto& nodeEntity : container) + { + if (nodeEntity) + { + if (auto listener = azrtti_cast(AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity))) + { + listeners.push_back(listener); + } + } + } + } +} namespace ScriptCanvasEditor { @@ -84,7 +104,9 @@ namespace ScriptCanvasEditor auto* scriptCanvasAssetTarget = assetTarget.GetAs(); AZ_Assert(scriptCanvasAssetTarget, "This should be a ScriptCanvasAsset, as this is the only type we process!"); - if (scriptCanvasAssetTarget && m_serializeContext && streamSource) + if (m_serializeContext + && streamSource + && scriptCanvasAssetTarget) { streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData(); @@ -99,6 +121,7 @@ namespace ScriptCanvasEditor byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); AZ::JsonDeserializerSettings settings; settings.m_serializeContext = m_serializeContext; + settings.m_metadata.Create(); // attempt JSON deserialization... if (JSRU::LoadObjectFromStreamByType ( &scriptCanvasDataTarget @@ -106,20 +129,40 @@ namespace ScriptCanvasEditor , byteStreamSource , &settings).IsSuccess()) { - return AZ::Data::AssetHandler::LoadResult::LoadComplete; - } + if (auto graphData = scriptCanvasAssetTarget->GetScriptCanvasGraph() + ? scriptCanvasAssetTarget->GetScriptCanvasGraph()->GetGraphData() + : nullptr) + { + auto listeners = settings.m_metadata.Find(); + AZ_Assert(listeners, "Failed to create SerializationListeners"); + ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->m_nodes, *listeners); + + for (auto listener : *listeners) + { + listener->OnDeserialize(); + } + + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } + else + { + AZ_Warning("ScriptCanvas", false, "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JOSON"); + } + } #if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// - // ...if there is a failure, check if it is saved in the old format - byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); - // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... - if (AZ::Utils::LoadObjectFromStreamInPlace - ( byteStreamSource + else + {// ...if there is a failure, check if it is saved in the old format + byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); + // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... + if (AZ::Utils::LoadObjectFromStreamInPlace + (byteStreamSource , scriptCanvasDataTarget , m_serializeContext , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES))) - { - return AZ::Data::AssetHandler::LoadResult::LoadComplete; + { + return AZ::Data::AssetHandler::LoadResult::LoadComplete; + } } #endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) } @@ -146,11 +189,26 @@ namespace ScriptCanvasEditor namespace JSRU = AZ::JsonSerializationUtils; using namespace ScriptCanvas; - if (assetData && stream && m_serializeContext) + if (m_serializeContext + && stream + && assetData + && assetData->GetScriptCanvasGraph() + && assetData->GetScriptCanvasGraph()->GetGraphData()) { + auto graphData = assetData->GetScriptCanvasGraph()->GetGraphData(); AZ::JsonSerializerSettings settings; + settings.m_metadata.Create(); + auto listeners = settings.m_metadata.Find(); + AZ_Assert(listeners, "Failed to create SerializationListeners"); + ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->m_nodes, *listeners); settings.m_keepDefaults = false; settings.m_serializeContext = m_serializeContext; + + for (auto listener : *listeners) + { + listener->OnSerialize(); + } + return JSRU::SaveObjectToStream(&assetData->GetScriptCanvasData(), *stream, nullptr, &settings).IsSuccess(); } else diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja index ebf647c7e9..aec7f22344 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja @@ -44,18 +44,10 @@ namespace {{attribute_Namespace}} { {% endif %} {% set className = Class.attrib['Name'] %} -{% if Class.attrib['Base'] is defined %} -{% if Class.attrib['Base'].split(';')|length > 1 %} -{% set baseClass = Class.attrib['Base'].split(';')[0] %} -{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %} -{% else %} -{% set baseClass = Class.attrib['Base'] %} -{% set baseClasses = Class.attrib['Base'] %} -{% endif %} -{% else %} -{% set baseClass = "ScriptCanvas::Node" %} -{% set baseClasses = "ScriptCanvas::Node" %} -{% endif %} +{% set baseClassPair = [] %} +{% if macros.CreateBaseClassVariables(Class, baseClassPair) %}{% endif %} +{% set baseClass = baseClassPair[0] %} +{% set baseClasses = baseClassPair[1] %} ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index 04c030acce..752ffd8bef 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -4,6 +4,8 @@ For complete copyright and license terms please see the LICENSE at the root of t SPDX-License-Identifier: Apache-2.0 OR MIT #} +{% import 'ScriptCanvas_Macros.jinja' as macros %} + {% macro add_attribute(attribute, tags) %} {% set value = tags[attribute] %} {% if value is defined %} @@ -26,18 +28,11 @@ SPDX-License-Identifier: Apache-2.0 OR MIT #include "{{ xml.attrib['Include'] }}" {% for Class in xml.iter('Class') %} -{% if Class.attrib['Base'] is defined %} -{% if Class.attrib['Base'].split(';')|length > 1 %} -{% set baseClass = Class.attrib['Base'].split(';')[0] %} -{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) %} -{% else %} -{% set baseClass = Class.attrib['Base'] %} -{% set baseClasses = Class.attrib['Base'] %} -{% endif %} -{% else %} -{% set baseClass = "ScriptCanvas::Node" %} -{% set baseClasses = "ScriptCanvas::Node" %} -{% endif %} +{% set baseClassPair = [] %} +{% if macros.CreateBaseClassVariables(Class, baseClassPair) %}{% endif %} +{% set baseClass = baseClassPair[0] %} +{% set baseClasses = baseClassPair[1] %} + void {{ Class.attrib['QualifiedName'] }}::ConfigureSlots() { {{ baseClass }}::ConfigureSlots(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja index 508bf65454..ee2100d3f6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja @@ -173,11 +173,29 @@ AZStd::tuple<{{returnTypes|join(", ")}}> {# ------- #} +{# CreateBaseClassVariables #} +{# Creates "baseClass" and "baseClasses" variables to use when needed "baseClasses" is a comma separated list that in includes baseClass #} +{%- macro CreateBaseClassVariables(Class, baseClassPair) -%} +{% set baseAttrib = Class.attrib['Base'] %} +{% if baseAttrib is defined %} +{% if baseAttrib.split(';')|length > 1 %} +{% if baseClassPair.append(baseAttrib.split(';')[0]) %}{% endif %} +{% if baseClassPair.append(", ".join(baseAttrib.split(';'))) %}{% endif %} +{% else %} +{% if baseClassPair.append(baseAttrib) %}{% endif %} +{% if baseClassPair.append(baseAttrib) %}{% endif %} +{% endif %} +{% else %} +{% if baseClassPair.append("ScriptCanvas::Node") %}{% endif %} +{% if baseClassPair.append("ScriptCanvas::Node") %}{% endif %} +{% endif %} +{%- endmacro -%} +{# ------- #} {# ------------------------------------------------------------------------------------- #} {# NODEABLES #} -{# TODO-LS: This macro lacks parsing the parameters provided to a Contract tag #} +{# TODO: This macro lacks parsing the parameters provided to a Contract tag #} {%- macro AddContract(configurationName, item) -%} {% set contracts = [] %} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index e1af284e00..ea0c98fd60 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -2041,21 +2041,6 @@ namespace ScriptCanvas } } - void Datum::OnSerializeBegin() - { - if (m_type.GetType() == Data::eType::BehaviorContextObject) - { - if (BehaviorContextObjectPtr ptr = (*AZStd::any_cast(&m_storage.value))) - { - ptr->OnSerializeBegin(); - } - else - { - AZ_Error("ScriptCanvas", false, AZStd::string::format("Datum type (%s) failed to serialized, did not store BehaviorContextObjectPtr properly", m_type.GetAZType().ToString().c_str()).c_str()); - } - } - } - void Datum::OnDeserialize() { if (m_type.GetType() == Data::eType::BehaviorContextObject) @@ -2080,14 +2065,9 @@ namespace ScriptCanvas } #if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// - void Datum::OnReadBegin() - { - OnSerializeBegin(); - } - void Datum::OnWriteEnd() { - OnSerializeEnd(); + OnDeserialize(); } #endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index df94c32559..2566149b6f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -240,13 +240,6 @@ namespace ScriptCanvas class SerializeContextEventHandler : public AZ::SerializeContext::IEventHandler { public: - /// Called after we are done writing to the instance pointed by classPtr. - void OnReadBegin(void* classPtr) override - { - Datum* datum = reinterpret_cast(classPtr); - datum->OnReadBegin(); - } - /// Called after we are done writing to the instance pointed by classPtr. void OnWriteEnd(void* classPtr) override { @@ -352,13 +345,9 @@ namespace ScriptCanvas void OnDatumEdited(); - void OnSerializeBegin() override; - void OnDeserialize() override; #if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// - void OnReadBegin(); - void OnWriteEnd(); #endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h index 90d8814d16..4a3771221d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SerializationListener.h @@ -16,8 +16,7 @@ namespace ScriptCanvas AZ_RTTI(SerializationListener, "{CA4EE281-30B3-4928-BCD8-9305CE75E463}"); virtual ~SerializationListener() {} - virtual void OnSerializeBegin() {} - virtual void OnSerializeEnd() {} + virtual void OnSerialize() {} virtual void OnDeserialize() {} }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp index 2abeec6266..7bcf0b2282 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.cpp @@ -17,14 +17,6 @@ namespace ScriptCanvas { - void BehaviorContextObject::OnSerializeBegin() - { - if (!IsOwned()) - { - Clear(); - } - } - void BehaviorContextObject::Reflect(AZ::ReflectContext* reflection) { if (auto serializeContext = azrtti_cast(reflection)) @@ -104,6 +96,12 @@ namespace ScriptCanvas : BehaviorContextObjectPtr(aznew BehaviorContextObject(reference, GetAnyTypeInfoReference(typeID), referenceFlags)); } + void BehaviorContextObject::Deserialize(BehaviorContextObject& target, const AZ::BehaviorClass& behaviorClass, AZStd::any& source) + { + target.m_object = AZStd::move(AZStd::any(AZStd::any_cast(&source), GetAnyTypeInfoObject(behaviorClass))); + target.m_flags = Owned; + } + void BehaviorContextObject::release() { if (--m_referenceCount == 0) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index 8cb04801fc..b2e282dbe2 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -22,6 +22,7 @@ namespace AZ { class ReflectContext; + class BehaviorContextObjectSerializer; } namespace ScriptCanvas @@ -30,6 +31,7 @@ namespace ScriptCanvas { friend struct AZStd::IntrusivePtrCountPolicy; friend class Datum; + friend class AZ::BehaviorContextObjectSerializer; public: AZ_TYPE_INFO(BehaviorContextObject, "{B735214D-5182-4536-B748-61EC83C1F007}"); @@ -81,6 +83,8 @@ namespace ScriptCanvas AZ_INLINE static BehaviorContextObject* CreateDefaultHeap(const AZ::BehaviorClass& behaviorClass); + static void Deserialize(BehaviorContextObject& target, const AZ::BehaviorClass& behaviorClass, AZStd::any& source); + // use the SSO optimization on behavior class size ALIGNED with a placement new of behavior class create AZ_FORCE_INLINE static AnyTypeInfo GetAnyTypeInfoObject(const AZ::BehaviorClass& behaviorClass); @@ -104,10 +108,10 @@ namespace ScriptCanvas //...so don't use the ctors, use the Create functions... //...the friend declarations are here for compatibility with the serialization system only AZ_FORCE_INLINE BehaviorContextObject() = default; - - BehaviorContextObject& operator=(const BehaviorContextObject&) = delete; - - BehaviorContextObject(const BehaviorContextObject&) = delete; + BehaviorContextObject& operator=(const BehaviorContextObject&) = default; + BehaviorContextObject(const BehaviorContextObject&) = default; + BehaviorContextObject(BehaviorContextObject&&) = default; + BehaviorContextObject& operator=(BehaviorContextObject&& source) = default; // copy ctor AZ_FORCE_INLINE BehaviorContextObject(const void* source, const AnyTypeInfo& typeInfo, AZ::u32 flags); @@ -119,8 +123,6 @@ namespace ScriptCanvas AZ_FORCE_INLINE bool IsOwned() const; - void OnSerializeBegin(); - AZ_FORCE_INLINE void add_ref(); void release(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp index 6de72af292..f49fcb3318 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.cpp @@ -188,6 +188,7 @@ namespace ScriptCanvas RefreshActiveIndexes(); ConfigureContracts(); + SetWarnOnMissingFunction(true); } SlotId MethodOverloaded::AddMethodInputSlot(const MethodConfiguration& config, size_t argumentIndex) @@ -400,10 +401,6 @@ namespace ScriptCanvas } #if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// - void MethodOverloaded::OnWriteBegin() - { - } - void MethodOverloaded::OnWriteEnd() { OnDeserialize(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h index 5c92bf1841..b880f68862 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/MethodOverloaded.h @@ -97,8 +97,7 @@ namespace ScriptCanvas // SerializeContextReadWriteHandler void OnReadBegin() {} void OnReadEnd() {} - - void OnWriteBegin(); + void OnWriteBegin() {} void OnWriteEnd(); #endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp new file mode 100644 index 0000000000..0f965b012f --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +using namespace ScriptCanvas; + +namespace AZ +{ + AZ_CLASS_ALLOCATOR_IMPL(BehaviorContextObjectSerializer, SystemAllocator, 0); + + JsonSerializationResult::Result BehaviorContextObjectSerializer::Load + ( void* outputValue + , [[maybe_unused]] const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "BehaviorContextObjectSerializer Load against output typeID" + "that was not BehaviorContextObject"); + AZ_Assert(outputValue, "BehaviorContextObjectSerializer Load against null output"); + + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + auto outputBehaviorContextObject = reinterpret_cast(outputValue); + + bool isOwned = false; + result.Combine(ContinueLoadingFromJsonObjectField + ( &isOwned + , azrtti_typeid() + , inputValue + , "isOwned" + , context)); + + if (isOwned) + { + AZStd::any storage; + { // any storage begin + + auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); + if (typeIdMember == inputValue.MemberEnd()) + { + return context.Report + (JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , AZStd::string::format("BehaviorContextObjectSerializer::Load failed to load the %s member" + , JsonSerialization::TypeIdFieldIdentifier)); + } + + AZ::Uuid typeId; + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic + , "BehaviorContextObjectSerializer::Load failed to load the AZ TypeId of the value"); + } + + storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "BehaviorContextObjectSerializer::Load failed to load a value matched the reported AZ " + "TypeId. The C++ declaration may have been deleted or changed."); + } + + result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "value", context)); + } // any storage end + + auto bcClass = AZ::BehaviorContextHelper::GetClass(storage.type()); + BehaviorContextObject::Deserialize(*outputBehaviorContextObject, *bcClass, storage); + } + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "BehaviorContextObjectSerializer Load finished loading BehaviorContextObject" + : "BehaviorContextObjectSerializer Load failed to load BehaviorContextObject"); + } + + JsonSerializationResult::Result BehaviorContextObjectSerializer::Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , [[maybe_unused]] const Uuid& valueTypeId + , JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid(), "BehaviorContextObjectSerializer Store against value typeID that " + "was not BehaviorContextObject"); + AZ_Assert(inputValue, "BehaviorContextObjectSerializer Store against null inputValue pointer "); + + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + auto inputScriptDataPtr = reinterpret_cast(inputValue); + + if (defaultScriptDataPtr) + { + if (AZ::Helpers::CompareAnyValue(inputScriptDataPtr->ToAny(), defaultScriptDataPtr->ToAny())) + { + return context.Report + ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "BehaviorContextObjectSerializer Store used defaults " + "for BehaviorContextObject"); + } + } + + outputValue.SetObject(); + JSR::ResultCode result(JSR::Tasks::WriteValue); + const bool isInputOwned = inputScriptDataPtr->IsOwned(); + const bool isDefaultOwned = defaultScriptDataPtr ? defaultScriptDataPtr->IsOwned() : false; + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "isOwned" + , &isInputOwned + , &isDefaultOwned + , azrtti_typeid() + , context)); + + if (isInputOwned) + { + // any storage begin + { + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->ToAny().type(), context)); + outputValue.AddMember + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(typeValue) + , context.GetJsonAllocator()); + } + + result.Combine(ContinueStoringToJsonObjectField + ( outputValue + , "value" + , inputScriptDataPtr->Get() + , defaultScriptDataPtr ? defaultScriptDataPtr->Get() : nullptr + , inputScriptDataPtr->ToAny().type() + , context)); + // datum storage end + } + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "BehaviorContextObjectSerializer Store finished saving BehaviorContextObject" + : "BehaviorContextObjectSerializer Store failed to save BehaviorContextObject"); + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h similarity index 86% rename from Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h rename to Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h index e7f91eccb3..012bb71680 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h @@ -14,11 +14,11 @@ namespace AZ { - class GraphDataSerializer + class BehaviorContextObjectSerializer : public BaseJsonSerializer { public: - AZ_RTTI(GraphDataSerializer, "{2DFF5794-785F-4434-9314-52BB3EF1D00E}", BaseJsonSerializer); + AZ_RTTI(BehaviorContextObjectSerializer, "{88469C4C-923F-4508-A45C-33DDBB91074E}", BaseJsonSerializer); AZ_CLASS_ALLOCATOR_DECL; private: diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp index aecf0f3db7..5bfb69b11e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -50,10 +50,23 @@ namespace AZ , "scriptCanvasType" , context)); - AZStd::any storage; - { // datum storage begin - AZ::Uuid typeId = AZ::Uuid::CreateNull(); + // datum storage begin + auto isNullPointerMember = inputValue.FindMember("isNullPointer"); + if (isNullPointerMember == inputValue.MemberEnd()) + { + return context.Report + ( JSR::Tasks::ReadField + , JSR::Outcomes::Missing + , "DatumSerializer::Load failed to load the 'isNullPointer'' member"); + } + if (isNullPointerMember->value.GetBool()) + { + *outputDatum = Datum(scType, Datum::eOriginality::Original); + } + else + { + AZ::Uuid typeId = AZ::Uuid::CreateNull(); auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { @@ -71,7 +84,7 @@ namespace AZ , "DatumSerializer::Load failed to load the AZ TypeId of the value"); } - storage = context.GetSerializeContext()->CreateAny(typeId); + AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); if (storage.empty() || storage.type() != typeId) { return context.Report(result, "DatumSerializer::Load failed to load a value matched the reported AZ TypeId. " @@ -79,24 +92,25 @@ namespace AZ } result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "value", context)); + *outputDatum = Datum(scType, Datum::eOriginality::Original, AZStd::any_cast(&storage), scType.GetAZType()); } // datum storage end AZStd::string label; AZ_Assert(azrtti_typeidm_datumLabel)>() == azrtti_typeid() , "m_datumLabel type changed and won't load properly"); - result.Combine(ContinueLoadingFromJsonObjectField ( &label , azrtti_typeidm_datumLabel)>() , inputValue , "label" , context)); + outputDatum->SetLabel(label); - Datum copy(scType, Datum::eOriginality::Original, AZStd::any_cast(&storage), scType.GetAZType()); - copy.SetLabel(label); - *outputDatum = copy; - outputDatum->OnDeserialize(); - + if (auto listeners = context.GetMetadata().Find()) + { + listeners->push_back(outputDatum); + } + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "DatumSerializer Load finished loading Datum" : "DatumSerializer Load failed to load Datum"); @@ -126,8 +140,6 @@ namespace AZ } } - const_cast(inputScriptDataPtr)->OnSerializeBegin(); - JSR::ResultCode result(JSR::Tasks::WriteValue); outputValue.SetObject(); @@ -146,25 +158,31 @@ namespace AZ , defaultScriptDataPtr ? &defaultScriptDataPtr->GetType() : nullptr , azrtti_typeidGetType())>() , context)); - - { // datum storage begin - { - rapidjson::Value typeValue; - result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->GetType().GetAZType(), context)); - outputValue.AddMember - ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) - , AZStd::move(typeValue) - , context.GetJsonAllocator()); - } + + // datum storage begin + auto inputObjectSource = inputScriptDataPtr->GetAsDanger(); + outputValue.AddMember("isNullPointer", rapidjson::Value(inputObjectSource == nullptr), context.GetJsonAllocator()); + + if (inputObjectSource) + { + rapidjson::Value typeValue; + result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->GetType().GetAZType(), context)); + outputValue.AddMember + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(typeValue) + , context.GetJsonAllocator()); + + auto defaultObjectSource = defaultScriptDataPtr ? defaultScriptDataPtr->GetAsDanger() : nullptr; result.Combine(ContinueStoringToJsonObjectField ( outputValue , "value" - , inputScriptDataPtr->GetAsDanger() - , defaultScriptDataPtr ? defaultScriptDataPtr->GetAsDanger() : nullptr + , inputObjectSource + , defaultObjectSource , inputScriptDataPtr->GetType().GetAZType() , context)); - } // datum storage end + } + // datum storage end result.Combine(ContinueStoringToJsonObjectField ( outputValue @@ -174,7 +192,6 @@ namespace AZ , azrtti_typeidm_datumLabel)>() , context)); - const_cast(inputScriptDataPtr)->OnSerializeEnd(); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "DatumSerializer Store finished saving Datum" : "DatumSerializer Store failed to save Datum"); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp deleted file mode 100644 index ff284fce85..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. - * For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include -#include -#include -#include - -using namespace ScriptCanvas; - -namespace GraphDataSerializerCpp -{ - void CollectNodes(const GraphData::NodeContainer& container, SerializationListeners& listeners) - { - for (auto& nodeEntity : container) - { - if (nodeEntity) - { - if (auto listener = azrtti_cast(AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity))) - { - listeners.push_back(listener); - } - } - } - } -} - -namespace AZ -{ - AZ_CLASS_ALLOCATOR_IMPL(GraphDataSerializer, SystemAllocator, 0); - - JsonSerializationResult::Result GraphDataSerializer::Load - ( void* outputValue - , [[maybe_unused]] const Uuid& outputValueTypeId - , const rapidjson::Value& inputValue - , JsonDeserializerContext& context) - { - namespace JSR = JsonSerializationResult; - - AZ_Assert(outputValueTypeId == azrtti_typeid() - , "RuntimeVariableSerializer Load against output typeID that was not GraphData"); - AZ_Assert(outputValue, "RuntimeVariableSerializer Load against null output"); - context.GetMetadata().Add(SerializationListeners()); - JSR::ResultCode result(JSR::Tasks::ReadField); - result.Combine(ContinueLoading(outputValue, outputValueTypeId, inputValue, context, ContinuationFlags::NoTypeSerializer)); - auto listeners = context.GetMetadata().Find(); - AZ_Assert(listeners, "Failed to create SerializationListeners"); - GraphDataSerializerCpp::CollectNodes(reinterpret_cast(outputValue)->m_nodes, *listeners); - - for (auto listener : *listeners) - { - listener->OnDeserialize(); - } - - reinterpret_cast(outputValue)->OnDeserialized(); - - return context.Report(result, result.GetProcessing() != JSR::Processing::Halted - ? "GraphDataSerializer Load finished loading GraphData" - : "GraphDataSerializer Load failed to load GraphData"); - } - - JsonSerializationResult::Result GraphDataSerializer::Store - ( rapidjson::Value& outputValue - , const void* inputValue - , const void* defaultValue - , [[maybe_unused]] const Uuid& valueTypeId - , JsonSerializerContext& context) - { - namespace JSR = JsonSerializationResult; - - AZ_Assert(valueTypeId == azrtti_typeid() - , "RuntimeVariableSerializer Store against output typeID that was not GraphData"); - AZ_Assert(inputValue, "RuntimeVariableSerializer Store against null output"); - context.GetMetadata().Add(SerializationListeners()); - auto listeners = context.GetMetadata().Find(); - GraphDataSerializerCpp::CollectNodes(reinterpret_cast(inputValue)->m_nodes, *listeners); - - for (auto listener : *listeners) - { - listener->OnSerializeBegin(); - } - - JSR::ResultCode result(JSR::Tasks::WriteValue); - result.Combine(ContinueStoring(outputValue, inputValue, defaultValue, valueTypeId, context, ContinuationFlags::NoTypeSerializer)); - - for (auto listener : *listeners) - { - listener->OnSerializeEnd(); - } - - return context.Report(result, result.GetProcessing() != JSR::Processing::Halted - ? "GraphDataSerializer::Store finished storing GraphData" - : "GraphDataSerializer::Store failed to store GraphData"); - } -} diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp index 9069592755..26af95fa8e 100644 --- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -90,7 +90,7 @@ namespace ScriptCanvas if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context)) { jsonContext->Serializer()->HandlesType(); - jsonContext->Serializer()->HandlesType(); + jsonContext->Serializer()->HandlesType(); jsonContext->Serializer()->HandlesType(); } diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 49da9565f3..7984340b7a 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -540,10 +540,10 @@ set(FILES Include/ScriptCanvas/Profiler/Aggregator.cpp Include/ScriptCanvas/Profiler/DrillerEvents.h Include/ScriptCanvas/Profiler/DrillerEvents.cpp + Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.h + Include/ScriptCanvas/Serialization/BehaviorContextObjectSerializer.cpp Include/ScriptCanvas/Serialization/DatumSerializer.h Include/ScriptCanvas/Serialization/DatumSerializer.cpp - Include/ScriptCanvas/Serialization/GraphDataSerializer.cpp - Include/ScriptCanvas/Serialization/GraphDataSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.h Include/ScriptCanvas/Serialization/RuntimeVariableSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas index 54dbf2e35e..c7de07141a 100644 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas @@ -1,11310 +1,7032 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +{ + "Type": "JsonSerialization", + "Version": 1, + "ClassName": "ScriptCanvasData", + "ClassData": { + "m_scriptCanvas": { + "Id": { + "id": 31042647073491 + }, + "Name": "LY_SC_UnitTest_PathologicalFlowOfControl", + "Components": { + "Component_[3557501584054890409]": { + "$type": "{4D755CA9-AB92-462C-B24F-0B3376F19967} Graph", + "Id": 3557501584054890409, + "m_graphData": { + "m_nodes": [ + { + "Id": { + "id": 31059826942675 + }, + "Name": "EBusEventHandler", + "Components": { + "Component_[10251308001417185158]": { + "$type": "EBusEventHandler", + "Id": 10251308001417185158, + "Slots": [ + { + "id": { + "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Connect", + "toolTip": "Connect this event handler to the specified entity.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Disconnect", + "toolTip": "Disconnect this event handler.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnConnected", + "toolTip": "Signaled when a connection has taken place.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnDisconnected", + "toolTip": "Signaled when this event handler is disconnected.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{42C5EF09-0843-4478-8BFF-0401009FACEA}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnFailure", + "toolTip": "Signaled when it is not possible to connect this handler.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CC23FBA6-EBA5-43DF-AB98-3024D4A01B21}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{D85921A2-82C6-4DE1-8DB0-DC93E80CD72B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ScriptTimePoint", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{4C0F6AD4-0D4F-4354-AD4A-0C01E948245C}" + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ExecutionSlot:OnTick", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + }, + "IsLatent": true + }, + { + "id": { + "m_id": "{3F00BC02-DBFB-4D4C-B5FD-4BE1C831E7AF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Result: Number", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{3BAF3F8C-54A2-4AD7-82F2-9EBB4AEF48EF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ExecutionSlot:GetTickOrder", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + }, + "IsLatent": true + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Result: Number" + } + ], + "m_eventMap": [ + { + "Key": { + "Value": 1502188240 + }, + "Value": { + "m_eventName": "OnTick", + "m_eventId": { + "Value": 1502188240 + }, + "m_eventSlotId": { + "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" + }, + "m_parameterSlotIds": [ + { + "m_id": "{CC23FBA6-EBA5-43DF-AB98-3024D4A01B21}" + }, + { + "m_id": "{D85921A2-82C6-4DE1-8DB0-DC93E80CD72B}" + } + ], + "m_numExpectedArguments": 2 + } + }, + { + "Key": { + "Value": 1890826333 + }, + "Value": { + "m_eventName": "GetTickOrder", + "m_eventId": { + "Value": 1890826333 + }, + "m_eventSlotId": { + "m_id": "{3BAF3F8C-54A2-4AD7-82F2-9EBB4AEF48EF}" + }, + "m_resultSlotId": { + "m_id": "{3F00BC02-DBFB-4D4C-B5FD-4BE1C831E7AF}" + } + } + } + ], + "m_ebusName": "TickBus", + "m_busId": { + "Value": 1209186864 + }, + "m_autoConnectToGraphOwner": false + } + } + }, + { + "Id": { + "id": 31119956484819 + }, + "Name": "EBusEventHandler", + "Components": { + "Component_[10251308001417185158]": { + "$type": "EBusEventHandler", + "Id": 10251308001417185158, + "Slots": [ + { + "id": { + "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Connect", + "toolTip": "Connect this event handler to the specified entity.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Disconnect", + "toolTip": "Disconnect this event handler.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnConnected", + "toolTip": "Signaled when a connection has taken place.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnDisconnected", + "toolTip": "Signaled when this event handler is disconnected.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{42C5EF09-0843-4478-8BFF-0401009FACEA}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "OnFailure", + "toolTip": "Signaled when it is not possible to connect this handler.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CC23FBA6-EBA5-43DF-AB98-3024D4A01B21}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Number", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{D85921A2-82C6-4DE1-8DB0-DC93E80CD72B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ScriptTimePoint", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{4C0F6AD4-0D4F-4354-AD4A-0C01E948245C}" + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ExecutionSlot:OnTick", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + }, + "IsLatent": true + }, + { + "id": { + "m_id": "{3F00BC02-DBFB-4D4C-B5FD-4BE1C831E7AF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Result: Number", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{3BAF3F8C-54A2-4AD7-82F2-9EBB4AEF48EF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "ExecutionSlot:GetTickOrder", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + }, + "IsLatent": true + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Result: Number" + } + ], + "m_eventMap": [ + { + "Key": { + "Value": 1502188240 + }, + "Value": { + "m_eventName": "OnTick", + "m_eventId": { + "Value": 1502188240 + }, + "m_eventSlotId": { + "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" + }, + "m_parameterSlotIds": [ + { + "m_id": "{CC23FBA6-EBA5-43DF-AB98-3024D4A01B21}" + }, + { + "m_id": "{D85921A2-82C6-4DE1-8DB0-DC93E80CD72B}" + } + ], + "m_numExpectedArguments": 2 + } + }, + { + "Key": { + "Value": 1890826333 + }, + "Value": { + "m_eventName": "GetTickOrder", + "m_eventId": { + "Value": 1890826333 + }, + "m_eventSlotId": { + "m_id": "{3BAF3F8C-54A2-4AD7-82F2-9EBB4AEF48EF}" + }, + "m_resultSlotId": { + "m_id": "{3F00BC02-DBFB-4D4C-B5FD-4BE1C831E7AF}" + } + } + } + ], + "m_ebusName": "TickBus", + "m_busId": { + "Value": 1209186864 + }, + "m_autoConnectToGraphOwner": false + } + } + }, + { + "Id": { + "id": 31128546419411 + }, + "Name": "SC-Node(Or)", + "Components": { + "Component_[10667361034986907134]": { + "$type": "Or", + "Id": 10667361034986907134, + "Slots": [ + { + "id": { + "m_id": "{78999179-DFFF-450B-B66E-A4C4E1638F0C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{C5E1B10E-FDFA-45F8-B6AF-BD9C672986FC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Signal to perform the evaluation when desired.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7FED3519-4670-4B3D-B81F-44393C2D7787}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the result of the operation is true.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E2D1192C-902D-4C82-9DE4-BBC20B31A54B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the result of the operation is false.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E8D87D3B-0974-4937-BEC5-8AE3BED5EBC2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Value A", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{56CECF75-DEC3-4491-85E6-7C0CE4B950D4}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Value B", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Value A" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Value B" + } + ] + } + } + }, + { + "Id": { + "id": 31068416877267 + }, + "Name": "SC-Node(OperatorAdd)", + "Components": { + "Component_[10710360517941107527]": { + "$type": "OperatorAdd", + "Id": 10710360517941107527, + "Slots": [ + { + "id": { + "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5E66E5C1-AE26-4919-BFD7-66EC6DE9B7BB}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6EA79D99-58BC-485B-8015-3B85753F522A}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + }, + { + "id": { + "m_id": "{A0CEC830-6910-452B-B850-75B6F727C455}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{5AAA51D3-6C26-4D13-91E2-4D2A8B33C7F0}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Result", + "toolTip": "The result of the specified operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + } + ] + } + } + }, + { + "Id": { + "id": 31077006811859 + }, + "Name": "SC-Node(OperatorAdd)", + "Components": { + "Component_[10710360517941107527]": { + "$type": "OperatorAdd", + "Id": 10710360517941107527, + "Slots": [ + { + "id": { + "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5E66E5C1-AE26-4919-BFD7-66EC6DE9B7BB}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6EA79D99-58BC-485B-8015-3B85753F522A}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + }, + { + "id": { + "m_id": "{A0CEC830-6910-452B-B850-75B6F727C455}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{5AAA51D3-6C26-4D13-91E2-4D2A8B33C7F0}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Result", + "toolTip": "The result of the specified operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + } + ] + } + } + }, + { + "Id": { + "id": 31132841386707 + }, + "Name": "SC-Node(And)", + "Components": { + "Component_[11788551755091650733]": { + "$type": "And", + "Id": 11788551755091650733, + "Slots": [ + { + "id": { + "m_id": "{46CFA92C-E217-41E2-BC0A-C7C4BA7D3060}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{FAFAB55A-69F1-495D-82FC-7D36F7842DA9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Signal to perform the evaluation when desired.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5BDD309F-0047-43E9-A911-475E47A036EC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the result of the operation is true.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7438C80C-9044-442D-8C71-827AB7DC3F0B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the result of the operation is false.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0D33ACC4-1331-4F0C-AA29-8863E5312983}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Value A", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{E3D62E2D-145C-4931-9FC8-CFE6CEB2FF64}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Value B", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Value A" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Value B" + } + ] + } + } + }, + { + "Id": { + "id": 31150021255891 + }, + "Name": "SC-Node(ExtractProperty)", + "Components": { + "Component_[11797457255651779243]": { + "$type": "ExtractProperty", + "Id": 11797457255651779243, + "Slots": [ + { + "id": { + "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled assigns property values using the supplied source input", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AC7594DE-A7F0-4519-9E07-0350AEEB25E0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after all property haves have been pushed to the output slots", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0C6BA77F-004F-4229-963F-EF6D6912A5BB}" + }, + "DynamicTypeOverride": 1, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Source", + "toolTip": "The value on which to extract properties from.", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Source" + } + ], + "m_dataType": { + "m_type": 3 + } + } + } + }, + { + "Id": { + "id": 31154316223187 + }, + "Name": "SC-Node(ExtractProperty)", + "Components": { + "Component_[11797457255651779243]": { + "$type": "ExtractProperty", + "Id": 11797457255651779243, + "Slots": [ + { + "id": { + "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "When signaled assigns property values using the supplied source input", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AC7594DE-A7F0-4519-9E07-0350AEEB25E0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled after all property haves have been pushed to the output slots", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0C6BA77F-004F-4229-963F-EF6D6912A5BB}" + }, + "DynamicTypeOverride": 1, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Source", + "toolTip": "The value on which to extract properties from.", + "DisplayDataType": { + "m_type": 3 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Source" + } + ], + "m_dataType": { + "m_type": 3 + } + } + } + }, + { + "Id": { + "id": 31089891713747 + }, + "Name": "SC-Node(ForEach)", + "Components": { + "Component_[11912058231419650479]": { + "$type": "ForEach", + "Id": 11912058231419650479, + "Slots": [ + { + "id": { + "m_id": "{B107E73D-A250-4019-BBF7-9085AEE354B6}" + }, + "DynamicTypeOverride": 2, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Source", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 3089028177 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + } + }, + { + "id": { + "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Signaled upon node entry", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{B24CD5F3-DE2B-42E9-BD45-0BCFF5A3D4B9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Break", + "toolTip": "Stops the iteration when signaled", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{8A4B7BED-4921-4C08-B35B-56D129A630E9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Each", + "toolTip": "Signalled after each element of the container", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0DEFFE74-9D9C-4E18-AFA2-12B1657F7D1D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Finished", + "toolTip": "The container has been fully iterated over", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{EDA1A957-FC80-4305-9797-1CC2699D13F8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Boolean", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "isNullPointer": true, + "label": "Source" + } + ], + "m_sourceSlot": { + "m_id": "{B107E73D-A250-4019-BBF7-9085AEE354B6}" + }, + "m_previousTypeId": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}", + "m_propertySlots": [ + { + "m_propertySlotId": { + "m_id": "{EDA1A957-FC80-4305-9797-1CC2699D13F8}" + }, + "m_propertyType": { + "m_type": 0 + }, + "m_propertyName": "Boolean" + } + ] + } + } + }, + { + "Id": { + "id": 31145726288595 + }, + "Name": "SC-Node(ForEach)", + "Components": { + "Component_[11912058231419650479]": { + "$type": "ForEach", + "Id": 11912058231419650479, + "Slots": [ + { + "id": { + "m_id": "{B107E73D-A250-4019-BBF7-9085AEE354B6}" + }, + "DynamicTypeOverride": 2, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Source", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 3089028177 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + } + }, + { + "id": { + "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Signaled upon node entry", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{B24CD5F3-DE2B-42E9-BD45-0BCFF5A3D4B9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Break", + "toolTip": "Stops the iteration when signaled", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{8A4B7BED-4921-4C08-B35B-56D129A630E9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Each", + "toolTip": "Signalled after each element of the container", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{0DEFFE74-9D9C-4E18-AFA2-12B1657F7D1D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Finished", + "toolTip": "The container has been fully iterated over", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{EDA1A957-FC80-4305-9797-1CC2699D13F8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Boolean", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "isNullPointer": true, + "label": "Source" + } + ], + "m_sourceSlot": { + "m_id": "{B107E73D-A250-4019-BBF7-9085AEE354B6}" + }, + "m_previousTypeId": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}", + "m_propertySlots": [ + { + "m_propertySlotId": { + "m_id": "{EDA1A957-FC80-4305-9797-1CC2699D13F8}" + }, + "m_propertyType": { + "m_type": 0 + }, + "m_propertyName": "Boolean" + } + ] + } + } + }, + { + "Id": { + "id": 31115661517523 + }, + "Name": "SC-Node(OperatorMul)", + "Components": { + "Component_[13237430188878581756]": { + "$type": "OperatorMul", + "Id": 13237430188878581756, + "Slots": [ + { + "id": { + "m_id": "{2D2F75D9-A1FB-4D70-86EF-8518E119DB07}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7A580403-C074-4DAD-A65E-BF928EF19DC8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CD4A3CE3-F0A5-4E82-BC6D-1AD9F2596A7E}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "OperatorType": "Multiply", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 7 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + }, + { + "id": { + "m_id": "{D662CA74-64EF-4D8F-BC80-D222A4990F3E}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "OperatorType": "Multiply", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 7 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{EC0D7AE5-C51F-48EE-BD42-10712F131C57}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "OperatorType": "Multiply", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 7 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Result", + "toolTip": "The result of the specified operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 1.0, + "label": "Number" + } + ] + } + } + }, + { + "Id": { + "id": 31098481648339 + }, + "Name": "SC-Node(MarkComplete)", + "Components": { + "Component_[13763264706969284951]": { + "$type": "{E42861BD-1956-45AE-8DD7-CCFC1E3E5ACF} Method", + "Id": 13763264706969284951, + "Slots": [ + { + "isVisibile": false, + "id": { + "m_id": "{A438327C-87F6-43C3-A1E2-C4BDAADA8C5D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "EntityID: 0", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{D2BCC38E-DA18-41ED-9B80-DB5602A9DB26}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Report", + "toolTip": "additional notes for the test report", + "DisplayDataType": { + "m_type": 5 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{79C2ABDD-F20A-4042-BF5C-8C09DC9332C7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{11965287-6D28-49B7-B387-3728356C2E0D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 1 + }, + "isNullPointer": false, + "$type": "EntityId", + "value": { + "id": 4276206253 + } + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 5 + }, + "isNullPointer": false, + "$type": "{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9} AZStd::string", + "value": "", + "label": "Report" + } + ], + "methodType": 2, + "methodName": "Mark Complete", + "className": "Unit Testing", + "resultSlotIDs": [ + {} + ], + "prettyClassName": "Unit Testing" + } + } + }, + { + "Id": { + "id": 31094186681043 + }, + "Name": "SC-Node(Not)", + "Components": { + "Component_[17238549219073370854]": { + "$type": "Not", + "Id": 17238549219073370854, + "Slots": [ + { + "id": { + "m_id": "{54D7FBC6-7B2A-4A3E-AD8C-F28A7C4C353D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Value", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{41EB5D06-DA39-434B-81D5-3E82A375C897}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{120C810C-F84A-445F-82E1-FD06CD3AD9B7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Signal to perform the evaluation when desired.", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6E82DFA3-70F4-419F-9971-AD243313E8D9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the result of the operation is true.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5C53A008-E808-4D00-A4EC-AC6A0EFDAFB9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the result of the operation is false.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 0 + }, + "isNullPointer": false, + "$type": "bool", + "value": false, + "label": "Value" + } + ] + } + } + }, + { + "Id": { + "id": 31102776615635 + }, + "Name": "SC-Node(TargetedSequencer)", + "Components": { + "Component_[2375509582066284148]": { + "$type": "TargetedSequencer", + "Id": 2375509582066284148, + "Slots": [ + { + "id": { + "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{800E14B1-C788-4C7F-B4D4-76121DE547C9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{14CCF4FA-A3F5-41F7-B66C-BCFF9D5A61F8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Index", + "toolTip": "Select which [Out#] to trigger.", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{9828EDD9-2689-424C-9708-304D720B1348}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 1", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{4A1E25C6-E63B-4BC0-BBDE-533CA69C91C5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 2", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Index" + } + ] + } + } + }, + { + "Id": { + "id": 31158611190483 + }, + "Name": "SC-Node(TargetedSequencer)", + "Components": { + "Component_[2375509582066284148]": { + "$type": "TargetedSequencer", + "Id": 2375509582066284148, + "Slots": [ + { + "id": { + "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{800E14B1-C788-4C7F-B4D4-76121DE547C9}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{14CCF4FA-A3F5-41F7-B66C-BCFF9D5A61F8}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Index", + "toolTip": "Select which [Out#] to trigger.", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{9828EDD9-2689-424C-9708-304D720B1348}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 1", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{4A1E25C6-E63B-4BC0-BBDE-533CA69C91C5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 2", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Index" + } + ] + } + } + }, + { + "Id": { + "id": 31124251452115 + }, + "Name": "SC-Node(OperatorAdd)", + "Components": { + "Component_[4806888795455241210]": { + "$type": "OperatorAdd", + "Id": 4806888795455241210, + "Slots": [ + { + "id": { + "m_id": "{792F23CB-7356-4DCA-A186-69F2A0BBC063}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{775F77BE-A9EC-455D-B378-15D16A0BEA4F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{02291180-ECAE-4D8B-8A9D-F9E451A3416F}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + }, + { + "id": { + "m_id": "{CCC2E84B-A90B-460B-AD1A-A2CCFF94D56F}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Number", + "toolTip": "An operand to use in performing the specified Operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + } + }, + { + "id": { + "m_id": "{40B63F5F-29F6-4F92-9C11-E47653798827}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + { + "$type": "MathOperatorContract", + "NativeTypes": [ + { + "m_type": 3 + }, + { + "m_type": 6 + }, + { + "m_type": 8 + }, + { + "m_type": 9 + }, + { + "m_type": 10 + }, + { + "m_type": 11 + }, + { + "m_type": 12 + }, + { + "m_type": 14 + }, + { + "m_type": 15 + } + ] + } + ], + "slotName": "Result", + "toolTip": "The result of the specified operation", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1114760223 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DynamicGroup": { + "Value": 1114760223 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + } + ] + } + } + }, + { + "Id": { + "id": 31137136354003 + }, + "Name": "SC-Node((NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >)", + "Components": { + "Component_[5026503393630088694]": { + "$type": "(NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >", + "Id": 5026503393630088694, + "Slots": [ + { + "id": { + "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{2CD5D252-4872-41A2-9C9E-4B81AD9877B7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{765E9D80-9091-400F-858D-1C70FA1C25B2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Vector3: Source", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{33BC5FB6-AB79-4121-8C82-0F0EFE4FB7F5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Number: Tolerance", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{C30EA842-3E60-4B71-A5C9-D70BB9FACC53}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result: Boolean", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 8 + }, + "isNullPointer": false, + "$type": "Vector3", + "value": [ + 0.0, + 0.0, + 0.0 + ], + "label": "Vector3: Source" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 1e-7, + "label": "Number: Tolerance" + } + ], + "Initialized": true + } + } + }, + { + "Id": { + "id": 31162906157779 + }, + "Name": "SC-Node((NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >)", + "Components": { + "Component_[5026503393630088694]": { + "$type": "(NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >", + "Id": 5026503393630088694, + "Slots": [ + { + "id": { + "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{2CD5D252-4872-41A2-9C9E-4B81AD9877B7}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{765E9D80-9091-400F-858D-1C70FA1C25B2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Vector3: Source", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{33BC5FB6-AB79-4121-8C82-0F0EFE4FB7F5}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "Number: Tolerance", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{C30EA842-3E60-4B71-A5C9-D70BB9FACC53}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result: Boolean", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 8 + }, + "isNullPointer": false, + "$type": "Vector3", + "value": [ + 0.0, + 0.0, + 0.0 + ], + "label": "Vector3: Source" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 1e-7, + "label": "Number: Tolerance" + } + ], + "Initialized": true + } + } + }, + { + "Id": { + "id": 31055531975379 + }, + "Name": "SC-Node(MathExpression)", + "Components": { + "Component_[5840825893583504722]": { + "$type": "MathExpression", + "Id": 5840825893583504722, + "Slots": [ + { + "id": { + "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5E038FBC-9A4B-489C-AB3E-26F103B7102E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Output signal", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7E74B9C7-C879-4B82-965F-889F8824BDFC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "x", + "toolTip": "Value which replaces instances of {x} in the resulting expression.", + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{28E4C6B8-0099-4213-BA4A-C21CC6EC0A5E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "y", + "toolTip": "Value which replaces instances of {y} in the resulting expression.", + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{AE1904C5-683D-40CA-93F6-5F18D40512BF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result", + "toolTip": "The resulting string.", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 3.0, + "label": "x" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 4.0, + "label": "y" + } + ], + "m_format": "{x} + {y}", + "m_expressionTree": { + "Variables": [ + { + "Key": { + "Value": 2363233923 + }, + "Value": { + "SupportedTypes": [ + "{110C4B14-11A8-4E9D-8638-5051013A56AC}" + ], + "$type": "double", + "Value": 3.0 + } + }, + { + "Key": { + "Value": 4225443349 + }, + "Value": { + "SupportedTypes": [ + "{110C4B14-11A8-4E9D-8638-5051013A56AC}" + ], + "$type": "double", + "Value": 4.0 + } + } + ], + "VariableDisplayOrder": [ + "x", + "y" + ], + "Tokens": [ + { + "TokenInformation": { + "Id": 1, + "isEmptyAny": false, + "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", + "Value": { + "DisplayName": "x", + "NameHash": { + "Value": 2363233923 + } + } + } + }, + { + "TokenInformation": { + "Id": 1, + "isEmptyAny": false, + "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", + "Value": { + "DisplayName": "y", + "NameHash": { + "Value": 4225443349 + } + } + } + }, + { + "ParserId": 3499457960, + "TokenInformation": { + "Id": 0, + "isEmptyAny": true + } + } + ] + } + } + } + }, + { + "Id": { + "id": 31081301779155 + }, + "Name": "SC-Node(MathExpression)", + "Components": { + "Component_[5840825893583504722]": { + "$type": "MathExpression", + "Id": 5840825893583504722, + "Slots": [ + { + "id": { + "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{5E038FBC-9A4B-489C-AB3E-26F103B7102E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Output signal", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7E74B9C7-C879-4B82-965F-889F8824BDFC}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "x", + "toolTip": "Value which replaces instances of {x} in the resulting expression.", + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{28E4C6B8-0099-4213-BA4A-C21CC6EC0A5E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null + ], + "slotName": "y", + "toolTip": "Value which replaces instances of {y} in the resulting expression.", + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{AE1904C5-683D-40CA-93F6-5F18D40512BF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Result", + "toolTip": "The resulting string.", + "DisplayDataType": { + "m_type": 3 + }, + "DisplayGroup": { + "Value": 1997398926 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 3.0, + "label": "x" + }, + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 4.0, + "label": "y" + } + ], + "m_format": "{x} + {y}", + "m_expressionTree": { + "Variables": [ + { + "Key": { + "Value": 2363233923 + }, + "Value": { + "SupportedTypes": [ + "{110C4B14-11A8-4E9D-8638-5051013A56AC}" + ], + "$type": "double", + "Value": 3.0 + } + }, + { + "Key": { + "Value": 4225443349 + }, + "Value": { + "SupportedTypes": [ + "{110C4B14-11A8-4E9D-8638-5051013A56AC}" + ], + "$type": "double", + "Value": 4.0 + } + } + ], + "VariableDisplayOrder": [ + "x", + "y" + ], + "Tokens": [ + { + "TokenInformation": { + "Id": 1, + "isEmptyAny": false, + "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", + "Value": { + "DisplayName": "x", + "NameHash": { + "Value": 2363233923 + } + } + } + }, + { + "TokenInformation": { + "Id": 1, + "isEmptyAny": false, + "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", + "Value": { + "DisplayName": "y", + "NameHash": { + "Value": 4225443349 + } + } + } + }, + { + "ParserId": 3499457960, + "TokenInformation": { + "Id": 0, + "isEmptyAny": true + } + } + ] + } + } + } + }, + { + "Id": { + "id": 31107071582931 + }, + "Name": "SC-Node(OrderedSequencer)", + "Components": { + "Component_[5989899372375578125]": { + "$type": "OrderedSequencer", + "Id": 5989899372375578125, + "Slots": [ + { + "id": { + "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{425822FB-C61E-4493-98C3-3A05418BD029}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 31085596746451 + }, + "Name": "SC-Node(OrderedSequencer)", + "Components": { + "Component_[5989899372375578125]": { + "$type": "OrderedSequencer", + "Id": 5989899372375578125, + "Slots": [ + { + "id": { + "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{425822FB-C61E-4493-98C3-3A05418BD029}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{8FDC2E61-37AE-4E0F-82FE-7A4D9696123C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 1", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{1000AB91-55FB-4615-B0EE-306816CFE895}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 2", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 31046942040787 + }, + "Name": "SC-Node(IsNull)", + "Components": { + "Component_[6380535138172294808]": { + "$type": "IsNull", + "Id": 6380535138172294808, + "Slots": [ + { + "id": { + "m_id": "{AEAA495A-12CF-42CC-80FA-B4D67AB5EA99}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "IsReferenceTypeContract" + } + ], + "slotName": "Reference", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + } + }, + { + "id": { + "m_id": "{C17691F7-094B-4663-B2D6-F7726B8D14D2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Is Null", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AA375295-D5E8-473C-A073-08A2853E750E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the reference provided is null.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{342C520C-CA78-4261-91C9-629978B79BA3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the reference provided is not null.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "isNullPointer": true, + "label": "Reference" + } + ] + } + } + }, + { + "Id": { + "id": 31111366550227 + }, + "Name": "SC-Node(IsNull)", + "Components": { + "Component_[6380535138172294808]": { + "$type": "IsNull", + "Id": 6380535138172294808, + "Slots": [ + { + "id": { + "m_id": "{AEAA495A-12CF-42CC-80FA-B4D67AB5EA99}" + }, + "DynamicTypeOverride": 3, + "contracts": [ + { + "$type": "SlotTypeContract" + }, + null, + { + "$type": "IsReferenceTypeContract" + } + ], + "slotName": "Reference", + "DisplayDataType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "Descriptor": { + "ConnectionType": 1, + "SlotType": 2 + }, + "DataType": 1, + "IsReference": true, + "VariableReference": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + } + }, + { + "id": { + "m_id": "{C17691F7-094B-4663-B2D6-F7726B8D14D2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Is Null", + "DisplayDataType": { + "m_type": 0 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 2 + }, + "DataType": 1 + }, + { + "id": { + "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AA375295-D5E8-473C-A073-08A2853E750E}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "True", + "toolTip": "Signaled if the reference provided is null.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{342C520C-CA78-4261-91C9-629978B79BA3}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "False", + "toolTip": "Signaled if the reference provided is not null.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ], + "Datums": [ + { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "isNullPointer": true, + "label": "Reference" + } + ] + } + } + }, + { + "Id": { + "id": 31072711844563 + }, + "Name": "SC-Node(Start)", + "Components": { + "Component_[6709400654876708818]": { + "$type": "Start", + "Id": 6709400654876708818, + "Slots": [ + { + "id": { + "m_id": "{E1417C09-E03B-4EA9-B9EC-67F8EC862B69}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Signaled when the entity that owns this graph is fully activated.", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 31064121909971 + }, + "Name": "SC-Node(Once)", + "Components": { + "Component_[7505935143439181025]": { + "$type": "Once", + "Id": 7505935143439181025, + "Slots": [ + { + "id": { + "m_id": "{67E7AF1F-F028-4460-819A-3FA6B9135F7B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "toolTip": "Input signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{C6EB1567-2D26-4BC6-AC09-CB25183B1E0F}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Reset", + "toolTip": "Reset signal", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{922907EE-9B7C-49CF-80A2-0A9FF5CDCB8C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out", + "toolTip": "Output signal", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{BD2D869A-A1F9-4CA3-AFF7-D8134A36D56A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "On Reset", + "toolTip": "Triggered when Reset", + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 31141431321299 + }, + "Name": "SC-Node(OrderedSequencer)", + "Components": { + "Component_[8845125901058188451]": { + "$type": "OrderedSequencer", + "Id": 8845125901058188451, + "Slots": [ + { + "id": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{58EB3964-B87B-4C73-AD7B-532E4BBAD9E2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 1", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 2", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 3", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{60D9FB27-2CAC-412A-8B3B-2E4B4574FD56}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 4", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 5", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{F71323EC-F182-465B-8671-C83BB07B227A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 6", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AFCB2F92-E497-4BBD-92B4-1E731246B834}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 7", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{973D553A-3231-461F-B46A-9A868846BE0B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 8", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{251CF78F-0D57-4345-B80F-3947FBD30FCE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 9", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{99CB5CB4-FF23-4C2B-9FBB-94D7752FCE80}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 10", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 11", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 12", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 13", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 14", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7ECBB1CC-6F3A-442E-B063-2B143F26ECF0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 15", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{58AAA7C2-843B-4B0A-8451-B509284BFC6B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 16", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{C6B341C5-8F1F-4F38-96B1-07873BC03493}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 17", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + }, + { + "Id": { + "id": 31051237008083 + }, + "Name": "SC-Node(OrderedSequencer)", + "Components": { + "Component_[8845125901058188451]": { + "$type": "OrderedSequencer", + "Id": 8845125901058188451, + "Slots": [ + { + "id": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "In", + "Descriptor": { + "ConnectionType": 1, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 0", + "toolTip": "Output 0", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{58EB3964-B87B-4C73-AD7B-532E4BBAD9E2}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 1", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 2", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 3", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{60D9FB27-2CAC-412A-8B3B-2E4B4574FD56}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 4", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 5", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{F71323EC-F182-465B-8671-C83BB07B227A}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 6", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{AFCB2F92-E497-4BBD-92B4-1E731246B834}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 7", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{973D553A-3231-461F-B46A-9A868846BE0B}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 8", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{251CF78F-0D57-4345-B80F-3947FBD30FCE}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 9", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{99CB5CB4-FF23-4C2B-9FBB-94D7752FCE80}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 10", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 11", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 12", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 13", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 14", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{7ECBB1CC-6F3A-442E-B063-2B143F26ECF0}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 15", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{8BC13109-B3A3-4931-8E54-0DFC6383A274}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 16", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + }, + { + "id": { + "m_id": "{3ED549E3-C72F-4EC5-8CD6-2B8A36A8E503}" + }, + "contracts": [ + { + "$type": "SlotTypeContract" + } + ], + "slotName": "Out 17", + "DisplayGroup": { + "Value": 1020632324 + }, + "Descriptor": { + "ConnectionType": 2, + "SlotType": 1 + } + } + ] + } + } + } + ], + "m_connections": [ + { + "Id": { + "id": 31167201125075 + }, + "Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[11968085700009090183]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11968085700009090183, + "sourceEndpoint": { + "nodeId": { + "id": 31072711844563 + }, + "slotId": { + "m_id": "{E1417C09-E03B-4EA9-B9EC-67F8EC862B69}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31171496092371 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(For Each: In)", + "Components": { + "Component_[14051685564799899080]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 14051685564799899080, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31089891713747 + }, + "slotId": { + "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" + } + } + } + } + }, + { + "Id": { + "id": 31175791059667 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 1), destEndpoint=(And: In)", + "Components": { + "Component_[5835922357284603096]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 5835922357284603096, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{58EB3964-B87B-4C73-AD7B-532E4BBAD9E2}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31132841386707 + }, + "slotId": { + "m_id": "{FAFAB55A-69F1-495D-82FC-7D36F7842DA9}" + } + } + } + } + }, + { + "Id": { + "id": 31180086026963 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[11349254841334591199]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11349254841334591199, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31085596746451 + }, + "slotId": { + "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" + } + } + } + } + }, + { + "Id": { + "id": 31184380994259 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 3), destEndpoint=(Is Null: In)", + "Components": { + "Component_[11724175899893098283]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11724175899893098283, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31046942040787 + }, + "slotId": { + "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" + } + } + } + } + }, + { + "Id": { + "id": 31188675961555 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 4), destEndpoint=(Or: In)", + "Components": { + "Component_[15445788857322783773]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 15445788857322783773, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{60D9FB27-2CAC-412A-8B3B-2E4B4574FD56}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31128546419411 + }, + "slotId": { + "m_id": "{C5E1B10E-FDFA-45F8-B6AF-BD9C672986FC}" + } + } + } + } + }, + { + "Id": { + "id": 31192970928851 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 5), destEndpoint=(Switch: In)", + "Components": { + "Component_[9877129165904558121]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 9877129165904558121, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31158611190483 + }, + "slotId": { + "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" + } + } + } + } + }, + { + "Id": { + "id": 31197265896147 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 6), destEndpoint=(Not: In)", + "Components": { + "Component_[3561874480108576621]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 3561874480108576621, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{F71323EC-F182-465B-8671-C83BB07B227A}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31094186681043 + }, + "slotId": { + "m_id": "{120C810C-F84A-445F-82E1-FD06CD3AD9B7}" + } + } + } + } + }, + { + "Id": { + "id": 31201560863443 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 10), destEndpoint=(Add (+): In)", + "Components": { + "Component_[15711843380878163015]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 15711843380878163015, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{99CB5CB4-FF23-4C2B-9FBB-94D7752FCE80}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31124251452115 + }, + "slotId": { + "m_id": "{792F23CB-7356-4DCA-A186-69F2A0BBC063}" + } + } + } + } + }, + { + "Id": { + "id": 31205855830739 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 11), destEndpoint=(Math Expression: In)", + "Components": { + "Component_[10938060626218586852]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10938060626218586852, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31081301779155 + }, + "slotId": { + "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" + } + } + } + } + }, + { + "Id": { + "id": 31210150798035 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 12), destEndpoint=(IsZero: In)", + "Components": { + "Component_[7885809696299116611]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 7885809696299116611, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31162906157779 + }, + "slotId": { + "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" + } + } + } + } + }, + { + "Id": { + "id": 31214445765331 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 13), destEndpoint=(Extract Properties: In)", + "Components": { + "Component_[4352059250555138202]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4352059250555138202, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31154316223187 + }, + "slotId": { + "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" + } + } + } + } + }, + { + "Id": { + "id": 31218740732627 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 14), destEndpoint=(Add (+): In)", + "Components": { + "Component_[4078469470815155794]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4078469470815155794, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31068416877267 + }, + "slotId": { + "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" + } + } + } + } + }, + { + "Id": { + "id": 31223035699923 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 15), destEndpoint=(Multiply (*): In)", + "Components": { + "Component_[17350434400301914971]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 17350434400301914971, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{7ECBB1CC-6F3A-442E-B063-2B143F26ECF0}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31115661517523 + }, + "slotId": { + "m_id": "{2D2F75D9-A1FB-4D70-86EF-8518E119DB07}" + } + } + } + } + }, + { + "Id": { + "id": 31227330667219 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 14), destEndpoint=(Add (+): In)", + "Components": { + "Component_[2124314791740833510]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 2124314791740833510, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31077006811859 + }, + "slotId": { + "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" + } + } + } + } + }, + { + "Id": { + "id": 31231625634515 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(For Each: In)", + "Components": { + "Component_[14483355239609043570]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 14483355239609043570, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31145726288595 + }, + "slotId": { + "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" + } + } + } + } + }, + { + "Id": { + "id": 31235920601811 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4849582226410181010]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4849582226410181010, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31107071582931 + }, + "slotId": { + "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" + } + } + } + } + }, + { + "Id": { + "id": 31240215569107 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 13), destEndpoint=(Extract Properties: In)", + "Components": { + "Component_[16660742051689195679]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 16660742051689195679, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31150021255891 + }, + "slotId": { + "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" + } + } + } + } + }, + { + "Id": { + "id": 31244510536403 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 11), destEndpoint=(Math Expression: In)", + "Components": { + "Component_[761902755754097552]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 761902755754097552, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31055531975379 + }, + "slotId": { + "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" + } + } + } + } + }, + { + "Id": { + "id": 31248805503699 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 3), destEndpoint=(Is Null: In)", + "Components": { + "Component_[11478294740641420074]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11478294740641420074, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31111366550227 + }, + "slotId": { + "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" + } + } + } + } + }, + { + "Id": { + "id": 31253100470995 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 12), destEndpoint=(IsZero: In)", + "Components": { + "Component_[6172045094798670980]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 6172045094798670980, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31137136354003 + }, + "slotId": { + "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" + } + } + } + } + }, + { + "Id": { + "id": 31257395438291 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 5), destEndpoint=(Switch: In)", + "Components": { + "Component_[10417773454009289241]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10417773454009289241, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31102776615635 + }, + "slotId": { + "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" + } + } + } + } + }, + { + "Id": { + "id": 31261690405587 + }, + "Name": "srcEndpoint=(For Each: Each), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4836133045899771729]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4836133045899771729, + "sourceEndpoint": { + "nodeId": { + "id": 31089891713747 + }, + "slotId": { + "m_id": "{8A4B7BED-4921-4C08-B35B-56D129A630E9}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31265985372883 + }, + "Name": "srcEndpoint=(For Each: Finished), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[6237489035629954338]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 6237489035629954338, + "sourceEndpoint": { + "nodeId": { + "id": 31089891713747 + }, + "slotId": { + "m_id": "{0DEFFE74-9D9C-4E18-AFA2-12B1657F7D1D}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31270280340179 + }, + "Name": "srcEndpoint=(And: True), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4927775769680604779]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4927775769680604779, + "sourceEndpoint": { + "nodeId": { + "id": 31132841386707 + }, + "slotId": { + "m_id": "{5BDD309F-0047-43E9-A911-475E47A036EC}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31274575307475 + }, + "Name": "srcEndpoint=(And: False), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[12544845157105431583]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 12544845157105431583, + "sourceEndpoint": { + "nodeId": { + "id": 31132841386707 + }, + "slotId": { + "m_id": "{7438C80C-9044-442D-8C71-827AB7DC3F0B}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31278870274771 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[13496863929205474320]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 13496863929205474320, + "sourceEndpoint": { + "nodeId": { + "id": 31085596746451 + }, + "slotId": { + "m_id": "{425822FB-C61E-4493-98C3-3A05418BD029}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31283165242067 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 1), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[12523441803443343729]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 12523441803443343729, + "sourceEndpoint": { + "nodeId": { + "id": 31085596746451 + }, + "slotId": { + "m_id": "{8FDC2E61-37AE-4E0F-82FE-7A4D9696123C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31287460209363 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4247029149608940629]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4247029149608940629, + "sourceEndpoint": { + "nodeId": { + "id": 31085596746451 + }, + "slotId": { + "m_id": "{1000AB91-55FB-4615-B0EE-306816CFE895}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31291755176659 + }, + "Name": "srcEndpoint=(Is Null: True), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[2748837971044280491]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 2748837971044280491, + "sourceEndpoint": { + "nodeId": { + "id": 31046942040787 + }, + "slotId": { + "m_id": "{AA375295-D5E8-473C-A073-08A2853E750E}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31296050143955 + }, + "Name": "srcEndpoint=(Is Null: False), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[2379529025270594940]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 2379529025270594940, + "sourceEndpoint": { + "nodeId": { + "id": 31046942040787 + }, + "slotId": { + "m_id": "{342C520C-CA78-4261-91C9-629978B79BA3}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31300345111251 + }, + "Name": "srcEndpoint=(Or: True), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4662929964571753389]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4662929964571753389, + "sourceEndpoint": { + "nodeId": { + "id": 31128546419411 + }, + "slotId": { + "m_id": "{7FED3519-4670-4B3D-B81F-44393C2D7787}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31304640078547 + }, + "Name": "srcEndpoint=(Or: False), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[10410455197671109469]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10410455197671109469, + "sourceEndpoint": { + "nodeId": { + "id": 31128546419411 + }, + "slotId": { + "m_id": "{E2D1192C-902D-4C82-9DE4-BBC20B31A54B}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31308935045843 + }, + "Name": "srcEndpoint=(Switch: Out 0), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[10099436517331803126]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 10099436517331803126, + "sourceEndpoint": { + "nodeId": { + "id": 31158611190483 + }, + "slotId": { + "m_id": "{800E14B1-C788-4C7F-B4D4-76121DE547C9}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31313230013139 + }, + "Name": "srcEndpoint=(Switch: Out 1), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[11535766430360773447]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 11535766430360773447, + "sourceEndpoint": { + "nodeId": { + "id": 31158611190483 + }, + "slotId": { + "m_id": "{9828EDD9-2689-424C-9708-304D720B1348}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31317524980435 + }, + "Name": "srcEndpoint=(Switch: Out 2), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[3612784336888322174]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 3612784336888322174, + "sourceEndpoint": { + "nodeId": { + "id": 31158611190483 + }, + "slotId": { + "m_id": "{4A1E25C6-E63B-4BC0-BBDE-533CA69C91C5}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31321819947731 + }, + "Name": "srcEndpoint=(Not: True), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4611790098876313333]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4611790098876313333, + "sourceEndpoint": { + "nodeId": { + "id": 31094186681043 + }, + "slotId": { + "m_id": "{6E82DFA3-70F4-419F-9971-AD243313E8D9}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31326114915027 + }, + "Name": "srcEndpoint=(Not: False), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[3740076693359624525]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 3740076693359624525, + "sourceEndpoint": { + "nodeId": { + "id": 31094186681043 + }, + "slotId": { + "m_id": "{5C53A008-E808-4D00-A4EC-AC6A0EFDAFB9}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31330409882323 + }, + "Name": "srcEndpoint=(Add (+): Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[3850851395875718062]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 3850851395875718062, + "sourceEndpoint": { + "nodeId": { + "id": 31124251452115 + }, + "slotId": { + "m_id": "{775F77BE-A9EC-455D-B378-15D16A0BEA4F}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31334704849619 + }, + "Name": "srcEndpoint=(Math Expression: Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[3602036390975897875]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 3602036390975897875, + "sourceEndpoint": { + "nodeId": { + "id": 31081301779155 + }, + "slotId": { + "m_id": "{5E038FBC-9A4B-489C-AB3E-26F103B7102E}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31338999816915 + }, + "Name": "srcEndpoint=(IsZero: Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[17614443468886602012]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 17614443468886602012, + "sourceEndpoint": { + "nodeId": { + "id": 31162906157779 + }, + "slotId": { + "m_id": "{2CD5D252-4872-41A2-9C9E-4B81AD9877B7}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31343294784211 + }, + "Name": "srcEndpoint=(Extract Properties: Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[4800366554066352627]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4800366554066352627, + "sourceEndpoint": { + "nodeId": { + "id": 31154316223187 + }, + "slotId": { + "m_id": "{AC7594DE-A7F0-4519-9E07-0350AEEB25E0}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31347589751507 + }, + "Name": "srcEndpoint=(Add (+): Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[15231344167676276156]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 15231344167676276156, + "sourceEndpoint": { + "nodeId": { + "id": 31068416877267 + }, + "slotId": { + "m_id": "{5E66E5C1-AE26-4919-BFD7-66EC6DE9B7BB}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31351884718803 + }, + "Name": "srcEndpoint=(Multiply (*): Out), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[13866431563723516549]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 13866431563723516549, + "sourceEndpoint": { + "nodeId": { + "id": 31115661517523 + }, + "slotId": { + "m_id": "{7A580403-C074-4DAD-A65E-BF928EF19DC8}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31356179686099 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 16), destEndpoint=(TickBus Handler: Connect)", + "Components": { + "Component_[4065717098596350153]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4065717098596350153, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{8BC13109-B3A3-4931-8E54-0DFC6383A274}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31119956484819 + }, + "slotId": { + "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" + } + } + } + } + }, + { + "Id": { + "id": 31360474653395 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 17), destEndpoint=(TickBus Handler: Disconnect)", + "Components": { + "Component_[451545062627990235]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 451545062627990235, + "sourceEndpoint": { + "nodeId": { + "id": 31051237008083 + }, + "slotId": { + "m_id": "{3ED549E3-C72F-4EC5-8CD6-2B8A36A8E503}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31119956484819 + }, + "slotId": { + "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" + } + } + } + } + }, + { + "Id": { + "id": 31364769620691 + }, + "Name": "srcEndpoint=(TickBus Handler: OnConnected), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[16416933153170812903]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 16416933153170812903, + "sourceEndpoint": { + "nodeId": { + "id": 31119956484819 + }, + "slotId": { + "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31369064587987 + }, + "Name": "srcEndpoint=(TickBus Handler: OnDisconnected), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[16427931620012509498]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 16427931620012509498, + "sourceEndpoint": { + "nodeId": { + "id": 31119956484819 + }, + "slotId": { + "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31373359555283 + }, + "Name": "srcEndpoint=(TickBus Handler: ExecutionSlot:OnTick), destEndpoint=(Ordered Sequencer: In)", + "Components": { + "Component_[12537264777285639380]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 12537264777285639380, + "sourceEndpoint": { + "nodeId": { + "id": 31119956484819 + }, + "slotId": { + "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" + } + } + } + } + }, + { + "Id": { + "id": 31377654522579 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 16), destEndpoint=(TickBus Handler: Connect)", + "Components": { + "Component_[4140744289594349719]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 4140744289594349719, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{58AAA7C2-843B-4B0A-8451-B509284BFC6B}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31059826942675 + }, + "slotId": { + "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" + } + } + } + } + }, + { + "Id": { + "id": 31381949489875 + }, + "Name": "srcEndpoint=(Ordered Sequencer: Out 17), destEndpoint=(TickBus Handler: Disconnect)", + "Components": { + "Component_[6223827301708831635]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 6223827301708831635, + "sourceEndpoint": { + "nodeId": { + "id": 31141431321299 + }, + "slotId": { + "m_id": "{C6B341C5-8F1F-4F38-96B1-07873BC03493}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31059826942675 + }, + "slotId": { + "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" + } + } + } + } + }, + { + "Id": { + "id": 31386244457171 + }, + "Name": "srcEndpoint=(TickBus Handler: OnConnected), destEndpoint=(Once: In)", + "Components": { + "Component_[16328568633919858732]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 16328568633919858732, + "sourceEndpoint": { + "nodeId": { + "id": 31059826942675 + }, + "slotId": { + "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31064121909971 + }, + "slotId": { + "m_id": "{67E7AF1F-F028-4460-819A-3FA6B9135F7B}" + } + } + } + } + }, + { + "Id": { + "id": 31390539424467 + }, + "Name": "srcEndpoint=(TickBus Handler: OnDisconnected), destEndpoint=(Once: In)", + "Components": { + "Component_[5193640857027050517]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 5193640857027050517, + "sourceEndpoint": { + "nodeId": { + "id": 31059826942675 + }, + "slotId": { + "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31064121909971 + }, + "slotId": { + "m_id": "{67E7AF1F-F028-4460-819A-3FA6B9135F7B}" + } + } + } + } + }, + { + "Id": { + "id": 31394834391763 + }, + "Name": "srcEndpoint=(Once: Out), destEndpoint=(Mark Complete: In)", + "Components": { + "Component_[5213414421933364896]": { + "$type": "{64CA5016-E803-4AC4-9A36-BDA2C890C6EB} Connection", + "Id": 5213414421933364896, + "sourceEndpoint": { + "nodeId": { + "id": 31064121909971 + }, + "slotId": { + "m_id": "{922907EE-9B7C-49CF-80A2-0A9FF5CDCB8C}" + } + }, + "targetEndpoint": { + "nodeId": { + "id": 31098481648339 + }, + "slotId": { + "m_id": "{79C2ABDD-F20A-4042-BF5C-8C09DC9332C7}" + } + } + } + } + } + ] + }, + "m_assetType": "{3E2AC8CD-713F-453E-967F-29517F331784}", + "versionData": { + "_grammarVersion": 1, + "_runtimeVersion": 1 + }, + "m_variableCounter": 2, + "GraphCanvasData": [ + { + "Key": { + "id": 31042647073491 + }, + "Value": { + "ComponentData": { + "{5F84B500-8C45-40D1-8EFC-A5306B241444}": { + "$type": "SceneComponentSaveData", + "ViewParams": { + "Scale": 0.2579344, + "AnchorX": -2508.39013671875, + "AnchorY": 1461.6121826171876 + } + } + } + } + }, + { + "Key": { + "id": 31046942040787 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 1240.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{63DF2982-B424-4D30-BF05-9DA9DD5664EC}" + } + } + } + }, + { + "Key": { + "id": 31051237008083 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -480.0, + 2320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{AC1D06EF-C967-4F35-95BD-8D822F4A2CE7}" + } + } + } + }, + { + "Key": { + "id": 31055531975379 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 2980.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{C2544B7B-3AA0-4731-81CF-DA88A5E210EC}" + } + } + } + }, + { + "Key": { + "id": 31059826942675 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2080.0, + 4340.0 + ] + }, + "{9E81C95F-89C0-4476-8E82-63CCC4E52E04}": { + "$type": "EBusHandlerNodeDescriptorSaveData", + "DisplayConnections": true, + "EventIds": [ + { + "Value": 1502188240 + } + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{58CBCF78-2B53-43EB-85BE-309EDB183924}" + } + } + } + }, + { + "Key": { + "id": 31064121909971 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2420.0, + 4320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{0CC6067B-5802-4AB3-9FF4-C1DF2C283DBB}" + } + } + } + }, + { + "Key": { + "id": 31068416877267 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3780.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{D305A28C-D38B-4A34-BEA1-7E7AA92B853A}" + } + } + } + }, + { + "Key": { + "id": 31072711844563 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -900.0, + 2400.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{D3649B82-A382-47A3-8168-BC7BA0377449}" + } + } + } + }, + { + "Key": { + "id": 31077006811859 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 3720.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{ABCB6F4F-5683-4958-B544-E543B5591129}" + } + } + } + }, + { + "Key": { + "id": 31081301779155 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3040.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{32F17925-C934-4CC7-918A-3026954CABD6}" + } + } + } + }, + { + "Key": { + "id": 31085596746451 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 960.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{55307FED-8C26-4EC5-98B5-F080C79E784D}" + } + } + } + }, + { + "Key": { + "id": 31089891713747 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 400.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{F37ED565-54EF-4A7C-9FB4-ABA1A71A4A36}" + } + } + } + }, + { + "Key": { + "id": 31094186681043 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 2000.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5E0AD895-3D93-41F0-86D0-0A9DC4305145}" + } + } + } + }, + { + "Key": { + "id": 31098481648339 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TestingNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2640.0, + 4320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{90DEA5B5-B658-4163-964E-91DB8D0D0F91}" + } + } + } + }, + { + "Key": { + "id": 31102776615635 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 1680.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{E6DB84DC-F8BE-4C8E-BE0D-A0B96652B2C0}" + } + } + } + }, + { + "Key": { + "id": 31107071582931 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 900.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{12114A6E-22BE-4A7A-8211-7A1282B900EC}" + } + } + } + }, + { + "Key": { + "id": 31111366550227 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 1180.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{9952383B-0B57-43BB-B59C-501C3F2CDE30}" + } + } + } + }, + { + "Key": { + "id": 31115661517523 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 4020.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{E6E72236-4B7B-47AD-ABF9-08E0D1691F72}" + } + } + } + }, + { + "Key": { + "id": 31119956484819 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 340.0, + 4320.0 + ] + }, + "{9E81C95F-89C0-4476-8E82-63CCC4E52E04}": { + "$type": "EBusHandlerNodeDescriptorSaveData", + "DisplayConnections": true, + "EventIds": [ + { + "Value": 1502188240 + } + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{3B6A148E-D130-4461-BA4D-EF0C91E7B729}" + } + } + } + }, + { + "Key": { + "id": 31124251452115 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 2820.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{0F538778-0124-48B9-B8D8-DB50D3620953}" + } + } + } + }, + { + "Key": { + "id": 31128546419411 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 1460.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{0C7217EF-A630-46C6-A1C8-D4202697B60E}" + } + } + } + }, + { + "Key": { + "id": 31132841386707 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 700.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{F60EF486-6C8B-4943-B3F4-600F8148DE78}" + } + } + } + }, + { + "Key": { + "id": 31137136354003 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 3260.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{810D332E-6C30-437C-9BCA-DF663A237034}" + } + } + } + }, + { + "Key": { + "id": 31141431321299 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 1200.0, + 2660.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{05F42C5B-4887-4800-8422-D5E5C1361E5F}" + } + } + } + }, + { + "Key": { + "id": 31145726288595 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 340.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{EDABFAD6-F9B5-4490-8EC6-165291FF3588}" + } + } + } + }, + { + "Key": { + "id": 31150021255891 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 3520.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{EFAA6315-4594-4432-A71C-C50AC21A3B9C}" + } + } + } + }, + { + "Key": { + "id": 31154316223187 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3580.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{BB3891CA-9936-4F18-8552-8EB7F2D02206}" + } + } + } + }, + { + "Key": { + "id": 31158611190483 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 1740.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{E6746414-838B-4AF7-AC50-EBEB0D2C06C2}" + } + } + } + }, + { + "Key": { + "id": 31162906157779 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{AE920511-0E26-4EEF-ADAD-982BEA59BA94}" + } + } + } + } + ], + "StatisticsHelper": { + "InstanceCounter": [ + { + "Key": 1244476766431948410, + "Value": 3 + }, + { + "Key": 1675714605584791791, + "Value": 1 + }, + { + "Key": 1899400123866786017, + "Value": 2 + }, + { + "Key": 4199610336680704683, + "Value": 1 + }, + { + "Key": 4271004856738215795, + "Value": 4 + }, + { + "Key": 5842117451819972883, + "Value": 2 + }, + { + "Key": 7224637793062157918, + "Value": 2 + }, + { + "Key": 7441743364271812807, + "Value": 1 + }, + { + "Key": 10181512461692697578, + "Value": 2 + }, + { + "Key": 10204019744198319120, + "Value": 1 + }, + { + "Key": 11764063517792044591, + "Value": 2 + }, + { + "Key": 12702286953450386850, + "Value": 1 + }, + { + "Key": 14285852892804039565, + "Value": 2 + }, + { + "Key": 14502416192304263066, + "Value": 2 + }, + { + "Key": 14935618182048638376, + "Value": 1 + }, + { + "Key": 18321430858034101497, + "Value": 1 + } + ] + } + }, + "Component_[4373975411826598062]": { + "$type": "EditorGraphVariableManagerComponent", + "Id": 4373975411826598062, + "m_variableData": { + "m_nameVariableMap": [ + { + "Key": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + }, + "Value": { + "Datum": { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 3 + }, + "isNullPointer": false, + "$type": "double", + "value": 0.0, + "label": "Number" + }, + "VariableId": { + "m_id": "{0BA96D88-BF13-4810-B01C-CA513AF84440}" + }, + "VariableName": "Variable 2" + } + }, + { + "Key": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + }, + "Value": { + "Datum": { + "isOverloadedStorage": false, + "scriptCanvasType": { + "m_type": 4, + "m_azType": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7}" + }, + "isNullPointer": false, + "$type": "{B505B05D-57BF-5A45-9113-B3A2784E2CD7} AZStd::vector", + "value": [ + true, + true + ], + "label": "Array" + }, + "VariableId": { + "m_id": "{39DB51CB-AA6E-4B3A-93EC-D622C44B3F4B}" + }, + "VariableName": "Array_of_Bools" + } + } + ] + } + } + } + } + } +} \ No newline at end of file From 53dfb1a39e598c9c4335a5585702fd97fdaec866 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 20 Aug 2021 20:36:11 -0700 Subject: [PATCH 13/27] remove unnecessary ALIGN macros Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Math/Internal/SimdMathCommon_simd.inl | 46 +++++++++---------- Code/Framework/AzCore/AzCore/Math/SimdMath.h | 36 +++++++-------- Code/Framework/AzCore/AzCore/Math/Uuid.h | 2 +- Code/Framework/AzCore/AzCore/PlatformDef.h | 17 ------- .../AzCore/AzCore/UnitTest/TestTypes.h | 2 +- Code/Framework/AzCore/AzCore/std/any.h | 2 +- .../AzCore/AzCore/std/parallel/combinable.h | 2 +- .../containers/lock_free_stamped_queue.h | 2 +- .../AzCore/Debug/StackTracer_Windows.cpp | 2 +- Code/Framework/AzCore/Tests/AZStd/UserTypes.h | 2 +- Code/Framework/AzCore/Tests/Memory.cpp | 2 +- Code/Framework/AzCore/Tests/Outcome.cpp | 2 +- Code/Legacy/CryCommon/AndroidSpecific.h | 3 -- Code/Legacy/CryCommon/AppleSpecific.h | 7 --- Code/Legacy/CryCommon/Cry_Camera.h | 2 +- Code/Legacy/CryCommon/Cry_Matrix33.h | 1 - Code/Legacy/CryCommon/Cry_Matrix34.h | 6 ++- Code/Legacy/CryCommon/Cry_Matrix44.h | 6 ++- Code/Legacy/CryCommon/Cry_Quat.h | 22 --------- Code/Legacy/CryCommon/IShader.h | 19 ++++---- Code/Legacy/CryCommon/Linux32Specific.h | 3 -- Code/Legacy/CryCommon/Linux64Specific.h | 3 -- Code/Legacy/CryCommon/LinuxSpecific.h | 4 -- Code/Legacy/CryCommon/Win32specific.h | 6 --- Code/Legacy/CryCommon/Win64specific.h | 6 --- Code/Legacy/CryCommon/platform.h | 10 ---- Code/Legacy/CryCommon/platform_impl.cpp | 2 +- .../RHI/Code/Include/Atom/RHI.Reflect/Bits.h | 25 ---------- .../Atom/RHI.Reflect/BufferDescriptor.h | 4 -- .../Atom/RHI.Reflect/BufferViewDescriptor.h | 4 -- .../Atom/RHI.Reflect/ImageDescriptor.h | 4 -- .../Atom/RHI.Reflect/ImageViewDescriptor.h | 4 -- .../Atom/RHI.Reflect/IndirectBufferLayout.h | 4 -- .../Atom/RHI.Reflect/MultisampleState.h | 4 -- .../RHI.Reflect/PipelineLayoutDescriptor.h | 2 - .../Atom/RHI.Reflect/RenderAttachmentLayout.h | 2 - .../Include/Atom/RHI.Reflect/RenderStates.h | 4 -- .../Include/Atom/RHI.Reflect/SamplerState.h | 4 -- .../Code/Include/Atom/RHI/IndexBufferView.h | 4 -- .../Include/Atom/RHI/IndirectBufferView.h | 4 -- .../Code/Include/Atom/RHI/StreamBufferView.h | 4 -- .../Code/Source/RHI/ImagePoolResolver.h | 2 - Gems/Atom/RHI/Vulkan/Code/Source/RHI/Queue.h | 2 - .../RHI/Vulkan/Code/Source/RHI/RenderPass.h | 4 -- .../EMotionFX/Source/MorphTargetStandard.h | 5 +- .../Code/EMotionFX/Source/Transform.h | 5 +- Gems/EMotionFX/Code/MCore/Source/Config.h | 16 ------- Gems/EMotionFX/Code/MCore/Source/Matrix4.h | 5 +- .../ScriptCanvas/Data/BehaviorContextObject.h | 2 +- 49 files changed, 80 insertions(+), 251 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl b/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl index fc406f5862..46bd071637 100644 --- a/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl +++ b/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl @@ -12,29 +12,29 @@ namespace AZ { namespace Simd { - static AZ_ALIGN(constexpr float g_sinCoef1[4], 16) = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f }; - static AZ_ALIGN(constexpr float g_sinCoef2[4], 16) = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f }; - static AZ_ALIGN(constexpr float g_sinCoef3[4], 16) = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f }; - static AZ_ALIGN(constexpr float g_cosCoef1[4], 16) = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f }; - static AZ_ALIGN(constexpr float g_cosCoef2[4], 16) = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f }; - static AZ_ALIGN(constexpr float g_cosCoef3[4], 16) = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f }; - static AZ_ALIGN(constexpr float g_acosHiCoef1[4], 16) = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f }; - static AZ_ALIGN(constexpr float g_acosHiCoef2[4], 16) = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f }; - static AZ_ALIGN(constexpr float g_acosHiCoef3[4], 16) = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f }; - static AZ_ALIGN(constexpr float g_acosHiCoef4[4], 16) = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f }; - static AZ_ALIGN(constexpr float g_acosLoCoef1[4], 16) = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f }; - static AZ_ALIGN(constexpr float g_acosLoCoef2[4], 16) = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f }; - static AZ_ALIGN(constexpr float g_acosLoCoef3[4], 16) = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f }; - static AZ_ALIGN(constexpr float g_acosLoCoef4[4], 16) = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f }; - static AZ_ALIGN(constexpr float g_acosCoef1[4], 16) = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f }; - static AZ_ALIGN(constexpr float g_acosCoef2[4], 16) = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f }; - static AZ_ALIGN(constexpr float g_acosCoef3[4], 16) = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f }; - static AZ_ALIGN(constexpr float g_atanHiRange[4], 16) = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f }; - static AZ_ALIGN(constexpr float g_atanLoRange[4], 16) = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f }; - static AZ_ALIGN(constexpr float g_atanCoef1[4], 16) = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f }; - static AZ_ALIGN(constexpr float g_atanCoef2[4], 16) = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f }; - static AZ_ALIGN(constexpr float g_atanCoef3[4], 16) = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f }; - static AZ_ALIGN(constexpr float g_atanCoef4[4], 16) = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f }; + static constexpr alignas(16) float g_sinCoef1[4] = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f }; + static constexpr alignas(16) float g_sinCoef2[4] = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f }; + static constexpr alignas(16) float g_sinCoef3[4] = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f }; + static constexpr alignas(16) float g_cosCoef1[4] = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f }; + static constexpr alignas(16) float g_cosCoef2[4] = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f }; + static constexpr alignas(16) float g_cosCoef3[4] = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f }; + static constexpr alignas(16) float g_acosHiCoef1[4] = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f }; + static constexpr alignas(16) float g_acosHiCoef2[4] = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f }; + static constexpr alignas(16) float g_acosHiCoef3[4] = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f }; + static constexpr alignas(16) float g_acosHiCoef4[4] = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f }; + static constexpr alignas(16) float g_acosLoCoef1[4] = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f }; + static constexpr alignas(16) float g_acosLoCoef2[4] = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f }; + static constexpr alignas(16) float g_acosLoCoef3[4] = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f }; + static constexpr alignas(16) float g_acosLoCoef4[4] = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f }; + static constexpr alignas(16) float g_acosCoef1[4] = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f }; + static constexpr alignas(16) float g_acosCoef2[4] = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f }; + static constexpr alignas(16) float g_acosCoef3[4] = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f }; + static constexpr alignas(16) float g_atanHiRange[4] = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f }; + static constexpr alignas(16) float g_atanLoRange[4] = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f }; + static constexpr alignas(16) float g_atanCoef1[4] = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f }; + static constexpr alignas(16) float g_atanCoef2[4] = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f }; + static constexpr alignas(16) float g_atanCoef3[4] = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f }; + static constexpr alignas(16) float g_atanCoef4[4] = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f }; namespace Common { diff --git a/Code/Framework/AzCore/AzCore/Math/SimdMath.h b/Code/Framework/AzCore/AzCore/Math/SimdMath.h index a1f073d10d..3d07cd41e8 100644 --- a/Code/Framework/AzCore/AzCore/Math/SimdMath.h +++ b/Code/Framework/AzCore/AzCore/Math/SimdMath.h @@ -24,24 +24,24 @@ namespace AZ { namespace Simd { - static AZ_ALIGN(constexpr float g_vec1111[4], 16) = { 1.0f, 1.0f, 1.0f, 1.0f }; - static AZ_ALIGN(constexpr float g_vec1000[4], 16) = { 1.0f, 0.0f, 0.0f, 0.0f }; - static AZ_ALIGN(constexpr float g_vec0100[4], 16) = { 0.0f, 1.0f, 0.0f, 0.0f }; - static AZ_ALIGN(constexpr float g_vec0010[4], 16) = { 0.0f, 0.0f, 1.0f, 0.0f }; - static AZ_ALIGN(constexpr float g_vec0001[4], 16) = { 0.0f, 0.0f, 0.0f, 1.0f }; - static AZ_ALIGN(constexpr float g_Pi[4], 16) = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi }; - static AZ_ALIGN(constexpr float g_TwoPi[4], 16) = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi }; - static AZ_ALIGN(constexpr float g_HalfPi[4], 16) = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi }; - static AZ_ALIGN(constexpr float g_QuarterPi[4], 16) = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi }; - static AZ_ALIGN(constexpr float g_TwoOverPi[4], 16) = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi }; - static AZ_ALIGN(constexpr int32_t g_absMask[4], 16) = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff }; - static AZ_ALIGN(constexpr int32_t g_negateMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 }; - static AZ_ALIGN(constexpr int32_t g_negateXMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 }; - static AZ_ALIGN(constexpr int32_t g_negateYMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 }; - static AZ_ALIGN(constexpr int32_t g_negateZMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 }; - static AZ_ALIGN(constexpr int32_t g_negateWMask[4], 16) = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 }; - static AZ_ALIGN(constexpr int32_t g_negateXYZMask[4], 16) = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 }; - static AZ_ALIGN(constexpr int32_t g_wMask[4], 16) = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 }; + static constexpr alignas(16) float g_vec1111[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + static constexpr alignas(16) float g_vec1000[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + static constexpr alignas(16) float g_vec0100[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + static constexpr alignas(16) float g_vec0010[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + static constexpr alignas(16) float g_vec0001[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + static constexpr alignas(16) float g_Pi[4] = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi }; + static constexpr alignas(16) float g_TwoPi[4] = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi }; + static constexpr alignas(16) float g_HalfPi[4] = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi }; + static constexpr alignas(16) float g_QuarterPi[4] = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi }; + static constexpr alignas(16) float g_TwoOverPi[4] = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi }; + static constexpr alignas(16) int32_t g_absMask[4] = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff }; + static constexpr alignas(16) int32_t g_negateMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 }; + static constexpr alignas(16) int32_t g_negateXMask[4] = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 }; + static constexpr alignas(16) int32_t g_negateYMask[4] = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 }; + static constexpr alignas(16) int32_t g_negateZMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 }; + static constexpr alignas(16) int32_t g_negateWMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 }; + static constexpr alignas(16) int32_t g_negateXYZMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 }; + static constexpr alignas(16) int32_t g_wMask[4] = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 }; } } diff --git a/Code/Framework/AzCore/AzCore/Math/Uuid.h b/Code/Framework/AzCore/AzCore/Math/Uuid.h index 13f60002ca..ea920e45c8 100644 --- a/Code/Framework/AzCore/AzCore/Math/Uuid.h +++ b/Code/Framework/AzCore/AzCore/Math/Uuid.h @@ -174,7 +174,7 @@ namespace AZ } // or _m128i and VMX ??? - AZ_ALIGN(unsigned char data[16], 16); + alignas(16) unsigned char data[16]; }; } // namespace AZ diff --git a/Code/Framework/AzCore/AzCore/PlatformDef.h b/Code/Framework/AzCore/AzCore/PlatformDef.h index 47f45931ba..8d28d27959 100644 --- a/Code/Framework/AzCore/AzCore/PlatformDef.h +++ b/Code/Framework/AzCore/AzCore/PlatformDef.h @@ -88,15 +88,6 @@ # define AZ_FORCE_INLINE __forceinline -/// Aligns a declaration. -# define AZ_ALIGN(_decl, _alignment) \ - AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \ - __declspec(align(_alignment)) \ - _decl \ - AZ_POP_DISABLE_WARNING - -/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>()) -# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof(_type) /// Pointer will be aliased. # define AZ_MAY_ALIAS /// Function signature macro @@ -120,15 +111,7 @@ #define AZ_POP_DISABLE_DLL_EXPORT_MEMBER_WARNING # define AZ_FORCE_INLINE inline -/// Aligns a declaration. -# define AZ_ALIGN(_decl, _alignment) \ - AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \ - _decl \ - __attribute__((aligned(_alignment))) - AZ_POP_DISABLE_WARNING -/// Return the alignment of a type. This if for internal use only (use AZStd::alignment_of<>()) -# define AZ_INTERNAL_ALIGNMENT_OF(_type) __alignof__(_type) /// Pointer will be aliased. # define AZ_MAY_ALIAS __attribute__((__may_alias__)) /// Function signature macro diff --git a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h index a7aa731c09..eb5011bbfa 100644 --- a/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h +++ b/Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h @@ -162,7 +162,7 @@ namespace UnitTest struct CreationCounter { AZ_TYPE_INFO(CreationCounter, "{E9E35486-4366-4066-86E5-1A8CEB44198B}"); - AZ_ALIGN(int test[size / sizeof(int)], alignment); + alignas(alignment) int test[size / sizeof(int)]; static int s_count; static int s_copied; diff --git a/Code/Framework/AzCore/AzCore/std/any.h b/Code/Framework/AzCore/AzCore/std/any.h index c0e277c2d6..514f5a9c86 100644 --- a/Code/Framework/AzCore/AzCore/std/any.h +++ b/Code/Framework/AzCore/AzCore/std/any.h @@ -384,7 +384,7 @@ namespace AZStd */ union { - AZ_ALIGN(char m_buffer[Internal::ANY_SBO_BUF_SIZE], 32); // Used for objects smaller than SBO_BUF_SIZE + alignas(32) char m_buffer[Internal::ANY_SBO_BUF_SIZE]; // Used for objects smaller than SBO_BUF_SIZE void* m_pointer; // Pointer to large objects }; type_info m_typeInfo; diff --git a/Code/Framework/AzCore/AzCore/std/parallel/combinable.h b/Code/Framework/AzCore/AzCore/std/parallel/combinable.h index 89ba35b5a0..7d62a7b9ac 100644 --- a/Code/Framework/AzCore/AzCore/std/parallel/combinable.h +++ b/Code/Framework/AzCore/AzCore/std/parallel/combinable.h @@ -164,7 +164,7 @@ namespace AZStd //enough. struct Node { - AZ_ALIGN(T m_value, 64); //alignment to avoid cache line sharing + alignas(64) T m_value; //alignment to avoid cache line sharing thread::id m_threadId; Node* m_next; }; diff --git a/Code/Framework/AzCore/AzCore/std/parallel/containers/lock_free_stamped_queue.h b/Code/Framework/AzCore/AzCore/std/parallel/containers/lock_free_stamped_queue.h index 52fb9cccdf..26cb7f345a 100644 --- a/Code/Framework/AzCore/AzCore/std/parallel/containers/lock_free_stamped_queue.h +++ b/Code/Framework/AzCore/AzCore/std/parallel/containers/lock_free_stamped_queue.h @@ -21,7 +21,7 @@ namespace AZStd template struct lock_free_stamped_node_ptr { - AZ_ALIGN(struct lock_free_stamped_queue_node* m_node, 8); + alignas(8) struct lock_free_stamped_queue_node* m_node; unsigned int m_stamp; }; diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index c4a12730ad..f8f94ea2b3 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -1073,7 +1073,7 @@ cleanup: } HANDLE hThread = nativeThread; - AZ_ALIGN(CONTEXT context, 8); // Without this alignment the function randomly crashes in release. + CONTEXT alignas(8) context; // Without this alignment the function randomly crashes in release. context.ContextFlags = CONTEXT_ALL; GetThreadContext(hThread, &context); diff --git a/Code/Framework/AzCore/Tests/AZStd/UserTypes.h b/Code/Framework/AzCore/Tests/AZStd/UserTypes.h index 30e83d8f1c..1b8c210205 100644 --- a/Code/Framework/AzCore/Tests/AZStd/UserTypes.h +++ b/Code/Framework/AzCore/Tests/AZStd/UserTypes.h @@ -56,7 +56,7 @@ namespace UnitTestInternal } // We use this class on the stack often, so alignment more than 16 bytes will not work on all platforms. - AZ_ALIGN(int m_data, 16); + alignas(16) int m_data; bool m_isMoved; }; diff --git a/Code/Framework/AzCore/Tests/Memory.cpp b/Code/Framework/AzCore/Tests/Memory.cpp index e1bffc472b..ea6495755e 100644 --- a/Code/Framework/AzCore/Tests/Memory.cpp +++ b/Code/Framework/AzCore/Tests/Memory.cpp @@ -982,7 +982,7 @@ namespace UnitTest : m_data(data) {} ~MyClass() {} - AZ_ALIGN(int m_data, 32); + alignas(32) int m_data; }; // Explicitly doesn't have AZ_CLASS_ALLOCATOR class MyDerivedClass diff --git a/Code/Framework/AzCore/Tests/Outcome.cpp b/Code/Framework/AzCore/Tests/Outcome.cpp index a01f6915a4..ed3a56995f 100644 --- a/Code/Framework/AzCore/Tests/Outcome.cpp +++ b/Code/Framework/AzCore/Tests/Outcome.cpp @@ -86,7 +86,7 @@ namespace UnitTest struct Aligned16 { - AZ_ALIGN(char m_data, 16); + alignas(16) char m_data; }; //! Class that changes a value when it's created and destroyed. diff --git a/Code/Legacy/CryCommon/AndroidSpecific.h b/Code/Legacy/CryCommon/AndroidSpecific.h index cf4359ba47..cf63e58015 100644 --- a/Code/Legacy/CryCommon/AndroidSpecific.h +++ b/Code/Legacy/CryCommon/AndroidSpecific.h @@ -109,9 +109,6 @@ typedef unsigned char byte; #define INVALID_FILE_ATTRIBUTES (-1) -#define DEFINE_ALIGNED_DATA(type, name, alignment) \ - type __attribute__ ((aligned(alignment))) name; - #include "LinuxSpecific.h" // these functions do not exist int the wchar.h header #undef wscasecomp diff --git a/Code/Legacy/CryCommon/AppleSpecific.h b/Code/Legacy/CryCommon/AppleSpecific.h index cd3146403a..60ab80ade6 100644 --- a/Code/Legacy/CryCommon/AppleSpecific.h +++ b/Code/Legacy/CryCommon/AppleSpecific.h @@ -126,10 +126,6 @@ typedef uint8 byte; #define STDMETHODCALLTYPE #endif -#define _ALIGN(num) \ - __attribute__ ((aligned(num))) \ - AZ_POP_DISABLE_WARNING - #define _PACK __attribute__ ((packed)) // Safe memory freeing @@ -265,9 +261,6 @@ typedef union _LARGE_INTEGER #define INVALID_FILE_ATTRIBUTES (-1) -#define DEFINE_ALIGNED_DATA(type, name, alignment) \ - type __attribute__ ((aligned(alignment))) name; - #define BST_UNCHECKED 0x0000 #ifndef HRESULT_VALUES_DEFINED diff --git a/Code/Legacy/CryCommon/Cry_Camera.h b/Code/Legacy/CryCommon/Cry_Camera.h index 851611c8a6..3d9d25e3bb 100644 --- a/Code/Legacy/CryCommon/Cry_Camera.h +++ b/Code/Legacy/CryCommon/Cry_Camera.h @@ -2146,7 +2146,7 @@ inline uint8 CCamera::IsOBBVisible_EH(const Vec3& wpos, const OBB& obb, f32 usca //--- ADDITIONAL-TEST --- //------------------------------------------------------------------------------ -extern _MS_ALIGN(64) uint32 BoxSides[]; +extern alignas(64) uint32 BoxSides[]; // Description: // A box can easily straddle one of the view-frustum planes far diff --git a/Code/Legacy/CryCommon/Cry_Matrix33.h b/Code/Legacy/CryCommon/Cry_Matrix33.h index f6cdc43b59..075f07a896 100644 --- a/Code/Legacy/CryCommon/Cry_Matrix33.h +++ b/Code/Legacy/CryCommon/Cry_Matrix33.h @@ -1243,7 +1243,6 @@ struct Matrix33_tpl typedef Matrix33_tpl Matrix33; //always 32 bit typedef Matrix33_tpl Matrix33d; //always 64 bit typedef Matrix33_tpl Matrix33r; //variable float precision. depending on the target system it can be between 32, 64 or 80 bit -typedef _MS_ALIGN(16) Matrix33_tpl _ALIGN (16) Matrix33A; //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- diff --git a/Code/Legacy/CryCommon/Cry_Matrix34.h b/Code/Legacy/CryCommon/Cry_Matrix34.h index 0cc0c02d5f..dfc059c11e 100644 --- a/Code/Legacy/CryCommon/Cry_Matrix34.h +++ b/Code/Legacy/CryCommon/Cry_Matrix34.h @@ -1224,7 +1224,11 @@ struct Matrix34_tpl typedef Matrix34_tpl Matrix34; //always 32 bit typedef Matrix34_tpl Matrix34d;//always 64 bit typedef Matrix34_tpl Matrix34r;//variable float precision. depending on the target system it can be between 32, 64 or bit -typedef _MS_ALIGN(16) Matrix34_tpl _ALIGN (16) Matrix34A; +#if AZ_COMPILER_MSVC + typedef __declspec(align(16)) Matrix34_tpl Matrix34A; +#elif AZ_COMPILER_CLANG + typedef Matrix34_tpl __attribute__((aligned(16))) Matrix34A; +#endif //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- diff --git a/Code/Legacy/CryCommon/Cry_Matrix44.h b/Code/Legacy/CryCommon/Cry_Matrix44.h index cf0b790b0a..8304f7761e 100644 --- a/Code/Legacy/CryCommon/Cry_Matrix44.h +++ b/Code/Legacy/CryCommon/Cry_Matrix44.h @@ -666,7 +666,11 @@ struct Matrix44_tpl typedef Matrix44_tpl Matrix44; //always 32 bit typedef Matrix44_tpl Matrix44d; //always 64 bit typedef Matrix44_tpl Matrix44r; //variable float precision. depending on the target system it can be between 32, 64 or 80 bit -typedef _MS_ALIGN(16) Matrix44_tpl _ALIGN (16) Matrix44A; +#if AZ_COMPILER_MSVC + typedef __declspec(align(16)) Matrix44_tpl Matrix44A; +#elif AZ_COMPILER_CLANG + typedef Matrix44_tpl __attribute__((aligned(16))) Matrix44A; +#endif //---------------------------------------------------------------------------------- //---------------------------------------------------------------------------------- diff --git a/Code/Legacy/CryCommon/Cry_Quat.h b/Code/Legacy/CryCommon/Cry_Quat.h index 15b3c11334..b062c584b7 100644 --- a/Code/Legacy/CryCommon/Cry_Quat.h +++ b/Code/Legacy/CryCommon/Cry_Quat.h @@ -908,14 +908,6 @@ typedef Quat_tpl CryQuat; typedef Quat_tpl quaternionf; typedef Quat_tpl quaternion; -// alligned versions -#ifndef MAX_API_NUM -typedef DEFINE_ALIGNED_DATA (Quat, QuatA, 16); // typedef __declspec(align(16)) Quat_tpl CryQuatA; -typedef DEFINE_ALIGNED_DATA (Quatd, QuatrA, 32); // typedef __declspec(align(16)) Quat_tpl quaternionfA; -#endif - - - /*! * * The "inner product" or "dot product" operation. @@ -1425,11 +1417,6 @@ typedef QuatT_tpl QuatT; //always 32 bit typedef QuatT_tpl QuatTd;//always 64 bit typedef QuatT_tpl QuatTr;//variable float precision. depending on the target system it can be between 32, 64 or bit -// alligned versions -typedef DEFINE_ALIGNED_DATA (QuatT, QuatTA, 32); //wastest 4byte per quatT // typedef __declspec(align(16)) Quat_tpl QuatTA; -typedef DEFINE_ALIGNED_DATA (QuatTd, QuatTrA, 16); // typedef __declspec(align(16)) Quat_tpl QuatTrA; - - /*! * * Implements the multiplication operator: QuatT=Quatpos*Quat @@ -1711,10 +1698,6 @@ typedef QuatTS_tpl QuatTS; //always 64 bit typedef QuatTS_tpl QuatTSd;//always 64 bit typedef QuatTS_tpl QuatTSr;//variable float precision. depending on the target system it can be between 32, 64 or 80 bit -// alligned versions -typedef DEFINE_ALIGNED_DATA (QuatTS, QuatTSA, 16); // typedef __declspec(align(16)) Quat_tpl QuatTSA; -typedef DEFINE_ALIGNED_DATA (QuatTSd, QuatTSrA, 64); // typedef __declspec(align(16)) QuatTS_tpl QuatTSrA; - template ILINE QuatTS_tpl operator * (const QuatTS_tpl& a, const Quat_tpl& b) { @@ -1972,11 +1955,6 @@ typedef QuatTNS_tpl QuatTNS; typedef QuatTNS_tpl QuatTNSr; typedef QuatTNS_tpl QuatTNS_f64; -// alligned versions -typedef DEFINE_ALIGNED_DATA (QuatTNS, QuatTNSA, 16); -typedef DEFINE_ALIGNED_DATA (QuatTNSr, QuatTNSrA, 64); -typedef DEFINE_ALIGNED_DATA (QuatTNS_f64, QuatTNS_f64A, 64); - template ILINE QuatTNS_tpl operator * (const QuatTNS_tpl& a, const Quat_tpl& b) { diff --git a/Code/Legacy/CryCommon/IShader.h b/Code/Legacy/CryCommon/IShader.h index 6ae3bd73df..5f00eb56d3 100644 --- a/Code/Legacy/CryCommon/IShader.h +++ b/Code/Legacy/CryCommon/IShader.h @@ -753,7 +753,7 @@ struct SBending // Description: // Interface for the skinnable objects (renderer calls its functions to get the skinning data). // should only created by EF_CreateSkinningData -_MS_ALIGN(16) struct SSkinningData +struct alignas(16) SSkinningData { uint32 nNumBones; uint32 nHWSkinningFlags; @@ -768,9 +768,10 @@ _MS_ALIGN(16) struct SSkinningData // members below are for Software Skinning void* pCustomData; // client specific data, used for example for sw-skinning on animation side SSkinningData* pNextSkinningData; // List to the next element which needs SW-Skinning -} _ALIGN(16); + [[maybe_unused]] int m_padding[2]; // padding to avoid MSVC warning 4324 +}; -struct SRenderObjData +struct alignas(16) SRenderObjData { uintptr_t m_uniqueObjectId; @@ -837,7 +838,7 @@ struct SRenderObjData { AZ_UNUSED(pSizer); } -} _ALIGN(16); +}; ////////////////////////////////////////////////////////////////////// // Objects using in shader pipeline @@ -856,7 +857,7 @@ struct ShadowMapFrustum; /// It can be compiled into the platform specific efficient rendering compiled object. /// ////////////////////////////////////////////////////////////////////// -_MS_ALIGN(16) class CRenderObject +class alignas(16) CRenderObject { public: AZ_CLASS_ALLOCATOR(CRenderObject, AZ::LegacyAllocator, 0); @@ -929,6 +930,8 @@ public: PerInstanceConstantBufferKey m_PerInstanceConstantBufferKey; + [[maybe_unused]] int m_padding[1]; // padding to avoid MSVC warning 4324 + //! Embedded SRenderObjData, optional data carried by CRenderObject SRenderObjData m_data; @@ -1007,7 +1010,7 @@ protected: } friend class CRenderer; -} _ALIGN(16); +}; enum EResClassName { @@ -1200,8 +1203,8 @@ struct SEfTexModificator return false; } - _MS_ALIGN(16) Matrix44 m_TexGenMatrix _ALIGN(16); - _MS_ALIGN(16) Matrix44 m_TexMatrix _ALIGN(16); + alignas(16) Matrix44 m_TexGenMatrix; + alignas(16) Matrix44 m_TexMatrix; float m_Tiling[3]; float m_Offs[3]; diff --git a/Code/Legacy/CryCommon/Linux32Specific.h b/Code/Legacy/CryCommon/Linux32Specific.h index 6812ddb818..bb9931021b 100644 --- a/Code/Legacy/CryCommon/Linux32Specific.h +++ b/Code/Legacy/CryCommon/Linux32Specific.h @@ -91,9 +91,6 @@ typedef unsigned char byte; #define INVALID_FILE_ATTRIBUTES (-1) -#define DEFINE_ALIGNED_DATA(type, name, alignment) \ - type __attribute__ ((aligned(alignment))) name; - #include "LinuxSpecific.h" #define TARGET_DEFAULT_ALIGN (0x4U) diff --git a/Code/Legacy/CryCommon/Linux64Specific.h b/Code/Legacy/CryCommon/Linux64Specific.h index 4dcb5f1e84..07cb92f207 100644 --- a/Code/Legacy/CryCommon/Linux64Specific.h +++ b/Code/Legacy/CryCommon/Linux64Specific.h @@ -97,9 +97,6 @@ typedef uint8 byte; #define INVALID_FILE_ATTRIBUTES (-1) -#define DEFINE_ALIGNED_DATA(type, name, alignment) \ - type __attribute__ ((aligned(alignment))) name; - #include "LinuxSpecific.h" #define TARGET_DEFAULT_ALIGN (0x8U) diff --git a/Code/Legacy/CryCommon/LinuxSpecific.h b/Code/Legacy/CryCommon/LinuxSpecific.h index 17b465d4cb..b3e75476c9 100644 --- a/Code/Legacy/CryCommon/LinuxSpecific.h +++ b/Code/Legacy/CryCommon/LinuxSpecific.h @@ -83,10 +83,6 @@ typedef float FLOAT; #define STDMETHODCALLTYPE #endif -#define _ALIGN(num) \ - __attribute__ ((aligned(num))) \ - AZ_POP_DISABLE_WARNING - #define _PACK __attribute__ ((packed)) // Safe memory freeing diff --git a/Code/Legacy/CryCommon/Win32specific.h b/Code/Legacy/CryCommon/Win32specific.h index 62d32138b4..4fa116166b 100644 --- a/Code/Legacy/CryCommon/Win32specific.h +++ b/Code/Legacy/CryCommon/Win32specific.h @@ -101,12 +101,6 @@ int64 CryGetTicksPerSec(); } #endif -#define _MS_ALIGN(num) \ - AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \ - __declspec(align(num)) - -#define DEFINE_ALIGNED_DATA(type, name, alignment) _declspec(align(alignment)) type name; - #ifndef FILE_ATTRIBUTE_NORMAL #define FILE_ATTRIBUTE_NORMAL 0x00000080 #endif diff --git a/Code/Legacy/CryCommon/Win64specific.h b/Code/Legacy/CryCommon/Win64specific.h index 47c9c1aad9..e8c1b87f4d 100644 --- a/Code/Legacy/CryCommon/Win64specific.h +++ b/Code/Legacy/CryCommon/Win64specific.h @@ -84,12 +84,6 @@ int64 CryGetTicksPerSec(); } #endif -#define _MS_ALIGN(num) \ - AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") \ - __declspec(align(num)) - -#define DEFINE_ALIGNED_DATA(type, name, alignment) _declspec(align(alignment)) type name; - #ifndef FILE_ATTRIBUTE_NORMAL #define FILE_ATTRIBUTE_NORMAL 0x00000080 #endif diff --git a/Code/Legacy/CryCommon/platform.h b/Code/Legacy/CryCommon/platform.h index 1b541a293e..3b80079c0f 100644 --- a/Code/Legacy/CryCommon/platform.h +++ b/Code/Legacy/CryCommon/platform.h @@ -372,16 +372,6 @@ threadID CryGetCurrentThreadId(); #define __PACKED #endif -// Fallback for Alignment macro of GCC/CLANG (must be after the class definition) -#if !defined(_ALIGN) - #define _ALIGN(num) AZ_POP_DISABLE_WARNING -#endif - -// Fallback for Alignment macro of MSVC (must be before the class definition) -#if !defined(_MS_ALIGN) - #define _MS_ALIGN(num) AZ_PUSH_DISABLE_WARNING(4324, "-Wunknown-warning-option") -#endif - #if defined(AZ_RESTRICTED_PLATFORM) #define AZ_RESTRICTED_SECTION PLATFORM_H_SECTION_13 #include AZ_RESTRICTED_FILE(platform_h) diff --git a/Code/Legacy/CryCommon/platform_impl.cpp b/Code/Legacy/CryCommon/platform_impl.cpp index ecc196a49f..168b5fd253 100644 --- a/Code/Legacy/CryCommon/platform_impl.cpp +++ b/Code/Legacy/CryCommon/platform_impl.cpp @@ -339,7 +339,7 @@ inline void CryDebugStr([[maybe_unused]] const char* format, ...) */ } -_MS_ALIGN(64) uint32 BoxSides[0x40 * 8] = { +alignas(64) uint32 BoxSides[0x40 * 8] = { 0, 0, 0, 0, 0, 0, 0, 0, //00 0, 4, 6, 2, 0, 0, 0, 4, //01 7, 5, 1, 3, 0, 0, 0, 4, //02 diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Bits.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Bits.h index 6659383c2f..c3972c829e 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Bits.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/Bits.h @@ -279,28 +279,3 @@ namespace AZ }; } } - - -// Emits an error when padding is introduced into a struct. -#if defined (AZ_COMPILER_MSVC) - -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN \ - __pragma(warning(push)) \ - __pragma(warning(error : 4820)) - -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_END \ - __pragma(warning(pop)) - -#elif defined (AZ_COMPILER_CLANG) || defined (AZ_COMPILER_GCC) - -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic error \"-Wpadded\"") - -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_END \ - _Pragma("GCC diagnostic pop") - -#else -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN -#define AZ_ASSERT_NO_ALIGNMENT_PADDING_END -#endif diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h index 80c41bec25..c271045ed0 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferDescriptor.h @@ -67,8 +67,6 @@ namespace AZ BufferBindFlags GetBufferBindFlags(ScopeAttachmentUsage usage, ScopeAttachmentAccess access); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - /** * A buffer corresponds to a region of linear memory and used for rendering operations. * Its lifecycle is managed by buffer pools. @@ -103,8 +101,6 @@ namespace AZ /// The mask of queue classes supporting shared access of this resource. HardwareQueueClassMask m_sharedQueueMask = HardwareQueueClassMask::All; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferViewDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferViewDescriptor.h index 887cbcb9bb..3aadc8e7db 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferViewDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/BufferViewDescriptor.h @@ -19,8 +19,6 @@ namespace AZ namespace RHI { - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - //! Buffer views describe how to interpret a region of memory in a buffer. struct BufferViewDescriptor { @@ -85,7 +83,5 @@ namespace AZ // manual alignment padding char m_pad0 = 0, m_pad1 = 0, m_pad2 = 0; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageDescriptor.h index 17fb5e9207..a90d52ac21 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageDescriptor.h @@ -21,8 +21,6 @@ namespace AZ { ImageBindFlags GetImageBindFlags(ScopeAttachmentUsage usage, ScopeAttachmentAccess access); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - /** * Images are comprised of sub-resources corresponding to the number of mip-mip levels * and array slices. Image data is stored as pixels in opaque swizzled formats. Images @@ -111,8 +109,6 @@ namespace AZ uint32_t m_isCubemap = 0; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END - /// Returns whether mip 'A' is more detailed than mip 'B'. inline bool IsMipMoreDetailedThan(uint32_t mipA, uint32_t mipB) { diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageViewDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageViewDescriptor.h index cb0682e967..c9ca1856f3 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageViewDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/ImageViewDescriptor.h @@ -20,8 +20,6 @@ namespace AZ namespace RHI { - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - /** * Image views map to a range of mips / array slices in an image. */ @@ -124,7 +122,5 @@ namespace AZ /// This is needed because a texture array can have 1 layer only. uint32_t m_isArray = 0; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/IndirectBufferLayout.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/IndirectBufferLayout.h index 0cde499546..fd26d845f7 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/IndirectBufferLayout.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/IndirectBufferLayout.h @@ -42,8 +42,6 @@ namespace AZ AZ_DEFINE_ENUM_BITWISE_OPERATORS(AZ::RHI::IndirectCommandTiers); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - //! Arguments when setting an indirect Vertex Buffer View command. struct IndirectBufferViewArguments { @@ -84,8 +82,6 @@ namespace AZ IndirectBufferViewArguments m_vertexBufferArgs; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END - AZ_FORCE_INLINE bool operator==(const IndirectCommandDescriptor& lhs, const IndirectCommandDescriptor& rhs) { return diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/MultisampleState.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/MultisampleState.h index 1c4979b773..689e23562d 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/MultisampleState.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/MultisampleState.h @@ -19,8 +19,6 @@ namespace AZ namespace RHI { - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - // Defines a custom sample position when doing Multisample rendering. // Sample positions have the origin(0, 0) at the pixel top left. // Each of the X and Y coordinates are unsigned values in the range 0 (top / left) to Limits::Pipeline::MultiSampleCustomLocationGridSize - 1 (bottom / right). @@ -56,7 +54,5 @@ namespace AZ uint16_t m_samples = 1; uint16_t m_quality = 0; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PipelineLayoutDescriptor.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PipelineLayoutDescriptor.h index 31fcd9be10..216021a316 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PipelineLayoutDescriptor.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/PipelineLayoutDescriptor.h @@ -22,7 +22,6 @@ namespace AZ { namespace RHI { - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN struct ResourceBindingInfo { AZ_TYPE_INFO(ResourceBindingInfo, "{2B25FA97-21C2-4567-8F01-6A64F7B9DFF6}"); @@ -45,7 +44,6 @@ namespace AZ /// Register id of a resource. Register m_registerId = InvalidRegister; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END /** * This class describes binding information about the Shader Resource Group diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderAttachmentLayout.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderAttachmentLayout.h index 6bbf013261..9a3c3dd226 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderAttachmentLayout.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderAttachmentLayout.h @@ -23,7 +23,6 @@ namespace AZ { static const uint32_t InvalidRenderAttachmentIndex = Limits::Pipeline::RenderAttachmentCountMax; - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN //! Describes one render attachment that is part of a layout. struct RenderAttachmentDescriptor { @@ -91,7 +90,6 @@ namespace AZ //! List with the layout of each subpass. AZStd::array m_subpassLayouts; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END //! Describes the layout of a collection of subpasses and it defines which of the subpasses this //! configuration will be using. diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderStates.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderStates.h index d56e3e3fd5..ae2141a1e8 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderStates.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/RenderStates.h @@ -82,8 +82,6 @@ namespace AZ void ReflectRenderStateEnums(ReflectContext* context); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - struct RasterState { AZ_TYPE_INFO(RasterState, "{57D4BE50-EBE2-4ABE-90A4-C99BF2EA43FB}"); @@ -216,8 +214,6 @@ namespace AZ static constexpr int32_t RenderStates_InvalidInt = std::numeric_limits::max(); static constexpr float RenderStates_InvalidFloat = std::numeric_limits::max(); - AZ_ASSERT_NO_ALIGNMENT_PADDING_END - //! Merges any render states in stateToMerge into the result state object. //! The values in stateToMerge are only copied over into the result if they are //! not invalid (see also GetInvalidState below). diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/SamplerState.h b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/SamplerState.h index 46cc8525f3..2771d23495 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/SamplerState.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI.Reflect/SamplerState.h @@ -70,8 +70,6 @@ namespace AZ void ReflectSamplerStateEnums(ReflectContext* context); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - class SamplerState { public: @@ -107,8 +105,6 @@ namespace AZ float m_mipLodBias = 0.0f; BorderColor m_borderColor = BorderColor::TransparentBlack; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } AZ_TYPE_INFO_SPECIALIZE(RHI::FilterMode, "{CFAE2156-0293-4D71-87D5-68F5C9F98884}"); diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/IndexBufferView.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/IndexBufferView.h index 7219709109..5e2b244627 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/IndexBufferView.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/IndexBufferView.h @@ -24,8 +24,6 @@ namespace AZ uint32_t GetIndexFormatSize(IndexFormat indexFormat); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - class IndexBufferView { public: @@ -61,7 +59,5 @@ namespace AZ // Padding the size so it's 8 bytes aligned uint32_t m_pad = 0; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/IndirectBufferView.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/IndirectBufferView.h index 7014fd030c..aabb329434 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/IndirectBufferView.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/IndirectBufferView.h @@ -17,8 +17,6 @@ namespace AZ class Buffer; class IndirectBufferSignature; - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - //! Provides a view into a buffer, to be used as an indirect buffer. The content of the view is a contiguous //! list of commands sequences. It is provided to the RHI back-end at draw time. class IndirectBufferView @@ -62,7 +60,5 @@ namespace AZ // Padding the size so it's 8 bytes aligned uint32_t m_pad = 0; }; - - AZ_ASSERT_NO_ALIGNMENT_PADDING_END } } diff --git a/Gems/Atom/RHI/Code/Include/Atom/RHI/StreamBufferView.h b/Gems/Atom/RHI/Code/Include/Atom/RHI/StreamBufferView.h index 9c9a16e8df..df62cb84f8 100644 --- a/Gems/Atom/RHI/Code/Include/Atom/RHI/StreamBufferView.h +++ b/Gems/Atom/RHI/Code/Include/Atom/RHI/StreamBufferView.h @@ -18,8 +18,6 @@ namespace AZ class Buffer; class InputStreamLayout; - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - /** * Provides a view into a buffer, to be used as vertex stream. The content of the view is a contiguous * list of input vertex data. It is provided to the RHI back-end at draw time. @@ -68,8 +66,6 @@ namespace AZ uint32_t m_pad = 0; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END - /// Utility function for checking that the set of StreamBufferViews aligns with the InputStreamLayout bool ValidateStreamBufferViews(const InputStreamLayout& inputStreamLayout, AZStd::array_view streamBufferViews); } diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/ImagePoolResolver.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/ImagePoolResolver.h index d8c1b9378a..c93aa29988 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/ImagePoolResolver.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/ImagePoolResolver.h @@ -58,7 +58,6 @@ namespace AZ RHI::Origin m_offset; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN struct BarrierInfo { VkPipelineStageFlags m_srcStageMask = {}; @@ -67,7 +66,6 @@ namespace AZ bool operator==(const BarrierInfo& other) { return ::memcmp(this, &other, sizeof(BarrierInfo)) == 0; } }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END void EmmitBarriers(CommandList& commandList, const AZStd::vector& barriers) const; diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Queue.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Queue.h index 2c3a8ee2cc..5bf831eff5 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Queue.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/Queue.h @@ -23,7 +23,6 @@ namespace AZ class SwapChain; class Fence; - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN struct QueueId { uint32_t m_familyIndex = 0; @@ -32,7 +31,6 @@ namespace AZ bool operator==(const QueueId& other) const { return ::memcmp(this, &other, sizeof(other)) == 0; } bool operator!=(const QueueId& other) const { return !(*this == other); } }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END class Queue final : public RHI::DeviceObject diff --git a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RenderPass.h b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RenderPass.h index 3cc2ff3ba7..8aaef51bd0 100644 --- a/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RenderPass.h +++ b/Gems/Atom/RHI/Vulkan/Code/Source/RHI/RenderPass.h @@ -38,8 +38,6 @@ namespace AZ ~RenderPass() = default; static RHI::Ptr Create(); - AZ_ASSERT_NO_ALIGNMENT_PADDING_BEGIN - enum class AttachmentType : uint32_t { Color, // Color render target attachment @@ -98,8 +96,6 @@ namespace AZ SubpassAttachment m_depthStencilAttachment; }; - AZ_ASSERT_NO_ALIGNMENT_PADDING_END - struct Descriptor { size_t GetHash() const; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MorphTargetStandard.h b/Gems/EMotionFX/Code/EMotionFX/Source/MorphTargetStandard.h index c4187fd638..8737da7139 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MorphTargetStandard.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MorphTargetStandard.h @@ -98,15 +98,14 @@ namespace EMotionFX * Please keep in mind that the rotation is stored as non-delta value, while the position and scale are * stored as delta values. */ - struct EMFX_API MCORE_ALIGN_PRE(16) Transformation + struct EMFX_API alignas(16) Transformation { AZ::Quaternion m_rotation; /**< The rotation as absolute value. So not a delta value, but a target (absolute) rotation. */ AZ::Quaternion m_scaleRotation; /**< The scale rotation, as absolute value. */ AZ::Vector3 m_position; /**< The position as a delta, so the difference between the original and target position. */ AZ::Vector3 m_scale; /**< The scale as a delta, so the difference between the original and target scale. */ size_t m_nodeIndex; /**< The node number to apply this on. */ - } - MCORE_ALIGN_POST(16); + }; /** * The constructor. diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Transform.h b/Gems/EMotionFX/Code/EMotionFX/Source/Transform.h index 764de9e8f9..cb1489410d 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Transform.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Transform.h @@ -20,7 +20,7 @@ namespace EMotionFX enum EMotionExtractionFlags : uint8; - class EMFX_API MCORE_ALIGN_PRE(16) Transform + class EMFX_API alignas(16) Transform { MCORE_MEMORYOBJECTCATEGORY(Transform, MCore::MCORE_SIMD_ALIGNMENT, EMFX_MEMCATEGORY_TRANSFORM); @@ -142,6 +142,5 @@ namespace EMotionFX #ifndef EMFX_SCALE_DISABLED AZ::Vector3 m_scale; /**< The scale. */ #endif - } - MCORE_ALIGN_POST(16); + }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/MCore/Source/Config.h b/Gems/EMotionFX/Code/MCore/Source/Config.h index c753a45ec3..8367e0d4e2 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Config.h +++ b/Gems/EMotionFX/Code/MCore/Source/Config.h @@ -217,22 +217,6 @@ typedef uintptr_t uintPointer; #define NULL 0 #endif -// alignment macro -#if (MCORE_COMPILER == MCORE_COMPILER_MSVC || MCORE_COMPILER == MCORE_COMPILER_INTELC) - #define MCORE_ALIGN(NUMBYTES, X) __declspec(align(NUMBYTES)) X - #define MCORE_ALIGN_PRE(NUMBYTES) __declspec(align(NUMBYTES)) - #define MCORE_ALIGN_POST(NUMBYTES) -#elif (MCORE_COMPILER == MCORE_COMPILER_GCC) - #define MCORE_ALIGN(NUMBYTES, X) X __attribute__((aligned(NUMBYTES))) - #define MCORE_ALIGN_PRE(NUMBYTES) - #define MCORE_ALIGN_POST(NUMBYTES) __attribute__((aligned(NUMBYTES))) -#else - #define MCORE_ALIGN(NUMBYTES, X) X - #define MCORE_ALIGN_PRE(NUMBYTES) - #define MCORE_ALIGN_POST(NUMBYTES) -#endif - - // detect and enable OpenMP support #if defined(_OPENMP) #define MCORE_OPENMP_ENABLED diff --git a/Gems/EMotionFX/Code/MCore/Source/Matrix4.h b/Gems/EMotionFX/Code/MCore/Source/Matrix4.h index c136aa824e..5d6da79bf5 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Matrix4.h +++ b/Gems/EMotionFX/Code/MCore/Source/Matrix4.h @@ -69,8 +69,7 @@ namespace MCore * [Tx Ty Tz 1] // translation
* */ - MCORE_ALIGN_PRE(16) - class MCORE_API Matrix + class MCORE_API alignas(16) Matrix { public: /** @@ -910,7 +909,7 @@ namespace MCore float m_m16[16]; // 16 floats as 1D array float m44[4][4]; // as 2D array }; - } MCORE_ALIGN_POST(16); + }; // include inline code diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index ca4500eccc..47e2dc472b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -268,7 +268,7 @@ namespace ScriptCanvas AZ_INLINE BehaviorContextObject* BehaviorContextObject::CreateDefaultBuffer(const AZ::BehaviorClass& behaviorClass) { - AZ_ALIGN(char buffer[AZStd::Internal::ANY_SBO_BUF_SIZE], 32); + alignas(32) char buffer[AZStd::Internal::ANY_SBO_BUF_SIZE]; AZ::BehaviorObject object = InvokeConstructor(behaviorClass, AZStd::addressof(buffer)); auto bco = aznew BehaviorContextObject(object.m_address, GetAnyTypeInfoObject(behaviorClass), Owned); behaviorClass.m_destructor(object.m_address, behaviorClass.m_userData); From aafe7358336f0105fd999742b69f444977cc1a84 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 23 Aug 2021 12:11:55 -0700 Subject: [PATCH 14/27] Add JSON serialization to required ExpressionEvaluation class Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Source/ElementInformationSerializer.inl | 74 +- ...est_PathologicalFlowOfControl.scriptcanvas | 1588 ++++++++--------- 2 files changed, 837 insertions(+), 825 deletions(-) diff --git a/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl b/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl index 19d220a4f3..8d297571ad 100644 --- a/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl +++ b/Gems/ExpressionEvaluation/Code/Source/ElementInformationSerializer.inl @@ -28,6 +28,19 @@ namespace AZ private: using ElementInformation = ExpressionEvaluation::ElementInformation; + static const char* EmptyAnyIdentifier; + + static bool IsEmptyAny(const rapidjson::Value& typeId) + { + if (typeId.IsString()) + { + AZStd::string_view typeName(typeId.GetString(), typeId.GetStringLength()); + return typeName == EmptyAnyIdentifier; + } + + return false; + } + JsonSerializationResult::Result Load ( void* outputValue , const Uuid& outputValueTypeId @@ -50,44 +63,38 @@ namespace AZ , context)); // any storage begin - auto isEmptyAny = inputValue.FindMember("isEmptyAny"); - if (isEmptyAny == inputValue.MemberEnd()) - { - return context.Report - (JSR::Tasks::ReadField - , JSR::Outcomes::Missing - , "ElementInformationSerializer::Load failed to load the 'isEmptyAny'' member"); - } - - if (!isEmptyAny->value.GetBool()) { AZ::Uuid typeId = AZ::Uuid::CreateNull(); auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { return context.Report - (JSR::Tasks::ReadField + ( JSR::Tasks::ReadField , JSR::Outcomes::Missing , AZStd::string::format("ElementInformationSerializer::Load failed to load the %s member" , JsonSerialization::TypeIdFieldIdentifier)); } - result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); - if (typeId.IsNull()) + if (!IsEmptyAny(typeIdMember->value)) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic - , "ElementInformationSerializer::Load failed to load the AZ TypeId of the value"); - } + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic + , "ElementInformationSerializer::Load failed to load the AZ TypeId of the value"); + } - AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); - if (storage.empty() || storage.type() != typeId) - { - return context.Report(result, "ElementInformationSerializer::Load failed to load a value matched the " - "reported AZ TypeId. The C++ declaration may have been deleted or changed."); - } + AZStd::any storage = context.GetSerializeContext()->CreateAny(typeId); + if (storage.empty() || storage.type() != typeId) + { + return context.Report(result, "ElementInformationSerializer::Load failed to load a value matched the " + "reported AZ TypeId. The C++ declaration may have been deleted or changed."); + } - result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "Value", context)); - outputDatum->m_extraStore = storage; + result.Combine + ( ContinueLoadingFromJsonObjectField(AZStd::any_cast(&storage), typeId, inputValue, "Value", context)); + outputDatum->m_extraStore = storage; + } } // any storage end @@ -114,7 +121,7 @@ namespace AZ if (defaultScriptDataPtr) { if (inputScriptDataPtr->m_id == defaultScriptDataPtr->m_id - && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_extraStore, defaultScriptDataPtr->m_extraStore)) + && AZ::Helpers::CompareAnyValue(inputScriptDataPtr->m_extraStore, defaultScriptDataPtr->m_extraStore)) { return context.Report ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ElementInformation Store used defaults for " @@ -133,15 +140,12 @@ namespace AZ , azrtti_typeidm_id)>() , context)); - - outputValue.AddMember("isEmptyAny", rapidjson::Value(inputScriptDataPtr->m_extraStore.empty()), context.GetJsonAllocator()); - if (!inputScriptDataPtr->m_extraStore.empty()) { rapidjson::Value typeValue; result.Combine(StoreTypeId(typeValue, inputScriptDataPtr->m_extraStore.type(), context)); outputValue.AddMember - (rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) , AZStd::move(typeValue) , context.GetJsonAllocator()); @@ -154,6 +158,16 @@ namespace AZ , context)); } + else + { + rapidjson::Value emptyAny; + AZStd::string emptyAnyName(EmptyAnyIdentifier); + emptyAny.SetString(emptyAnyName.c_str(), aznumeric_caster(emptyAnyName.size()), context.GetJsonAllocator()); + outputValue.AddMember + ( rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier) + , AZStd::move(emptyAny) + , context.GetJsonAllocator()); + } return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "ElementInformation Store finished saving ElementInformation" @@ -162,4 +176,6 @@ namespace AZ }; AZ_CLASS_ALLOCATOR_IMPL(ElementInformationSerializer, SystemAllocator, 0); + + const char* ElementInformationSerializer::EmptyAnyIdentifier = "Empty AZStd::any"; } diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas index c7de07141a..f2666232d8 100644 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_PathologicalFlowOfControl.scriptcanvas @@ -5,7 +5,7 @@ "ClassData": { "m_scriptCanvas": { "Id": { - "id": 31042647073491 + "id": 31194166714268 }, "Name": "LY_SC_UnitTest_PathologicalFlowOfControl", "Components": { @@ -16,7 +16,7 @@ "m_nodes": [ { "Id": { - "id": 31059826942675 + "id": 31288655994780 }, "Name": "EBusEventHandler", "Components": { @@ -257,7 +257,7 @@ }, { "Id": { - "id": 31119956484819 + "id": 31314425798556 }, "Name": "EBusEventHandler", "Components": { @@ -498,7 +498,7 @@ }, { "Id": { - "id": 31128546419411 + "id": 31211346583452 }, "Name": "SC-Node(Or)", "Components": { @@ -635,7 +635,7 @@ }, { "Id": { - "id": 31068416877267 + "id": 31267181158300 }, "Name": "SC-Node(OperatorAdd)", "Components": { @@ -884,7 +884,7 @@ }, { "Id": { - "id": 31077006811859 + "id": 31305835863964 }, "Name": "SC-Node(OperatorAdd)", "Components": { @@ -1133,7 +1133,7 @@ }, { "Id": { - "id": 31132841386707 + "id": 31228526452636 }, "Name": "SC-Node(And)", "Components": { @@ -1270,7 +1270,7 @@ }, { "Id": { - "id": 31150021255891 + "id": 31232821419932 }, "Name": "SC-Node(ExtractProperty)", "Components": { @@ -1357,7 +1357,7 @@ }, { "Id": { - "id": 31154316223187 + "id": 31301540896668 }, "Name": "SC-Node(ExtractProperty)", "Components": { @@ -1444,7 +1444,7 @@ }, { "Id": { - "id": 31089891713747 + "id": 31224231485340 }, "Name": "SC-Node(ForEach)", "Components": { @@ -1596,7 +1596,7 @@ }, { "Id": { - "id": 31145726288595 + "id": 31284361027484 }, "Name": "SC-Node(ForEach)", "Components": { @@ -1748,7 +1748,7 @@ }, { "Id": { - "id": 31115661517523 + "id": 31215641550748 }, "Name": "SC-Node(OperatorMul)", "Components": { @@ -1964,7 +1964,7 @@ }, { "Id": { - "id": 31098481648339 + "id": 31202756648860 }, "Name": "SC-Node(MarkComplete)", "Components": { @@ -2077,7 +2077,7 @@ }, { "Id": { - "id": 31094186681043 + "id": 31280066060188 }, "Name": "SC-Node(Not)", "Components": { @@ -2187,7 +2187,7 @@ }, { "Id": { - "id": 31102776615635 + "id": 31258591223708 }, "Name": "SC-Node(TargetedSequencer)", "Components": { @@ -2304,7 +2304,7 @@ }, { "Id": { - "id": 31158611190483 + "id": 31297245929372 }, "Name": "SC-Node(TargetedSequencer)", "Components": { @@ -2421,7 +2421,7 @@ }, { "Id": { - "id": 31124251452115 + "id": 31310130831260 }, "Name": "SC-Node(OperatorAdd)", "Components": { @@ -2674,7 +2674,7 @@ }, { "Id": { - "id": 31137136354003 + "id": 31198461681564 }, "Name": "SC-Node((NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >)", "Components": { @@ -2798,7 +2798,7 @@ }, { "Id": { - "id": 31162906157779 + "id": 31207051616156 }, "Name": "SC-Node((NodeFunctionGenericMultiReturn)<{bool(Vector3 double )}* IsZeroTraits >)", "Components": { @@ -2922,7 +2922,7 @@ }, { "Id": { - "id": 31055531975379 + "id": 31219936518044 }, "Name": "SC-Node(MathExpression)", "Components": { @@ -3086,7 +3086,6 @@ { "TokenInformation": { "Id": 1, - "isEmptyAny": false, "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", "Value": { "DisplayName": "x", @@ -3099,7 +3098,6 @@ { "TokenInformation": { "Id": 1, - "isEmptyAny": false, "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", "Value": { "DisplayName": "y", @@ -3113,7 +3111,7 @@ "ParserId": 3499457960, "TokenInformation": { "Id": 0, - "isEmptyAny": true + "$type": "Empty AZStd::any" } } ] @@ -3123,7 +3121,7 @@ }, { "Id": { - "id": 31081301779155 + "id": 31241411354524 }, "Name": "SC-Node(MathExpression)", "Components": { @@ -3287,7 +3285,6 @@ { "TokenInformation": { "Id": 1, - "isEmptyAny": false, "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", "Value": { "DisplayName": "x", @@ -3300,7 +3297,6 @@ { "TokenInformation": { "Id": 1, - "isEmptyAny": false, "$type": "{6D219DB1-3763-4408-A3E8-75E4AE66E9BD} VariableDescriptor", "Value": { "DisplayName": "y", @@ -3314,7 +3310,7 @@ "ParserId": 3499457960, "TokenInformation": { "Id": 0, - "isEmptyAny": true + "$type": "Empty AZStd::any" } } ] @@ -3324,7 +3320,7 @@ }, { "Id": { - "id": 31107071582931 + "id": 31292950962076 }, "Name": "SC-Node(OrderedSequencer)", "Components": { @@ -3372,7 +3368,7 @@ }, { "Id": { - "id": 31085596746451 + "id": 31275771092892 }, "Name": "SC-Node(OrderedSequencer)", "Components": { @@ -3456,7 +3452,7 @@ }, { "Id": { - "id": 31046942040787 + "id": 31250001289116 }, "Name": "SC-Node(IsNull)", "Components": { @@ -3577,7 +3573,7 @@ }, { "Id": { - "id": 31111366550227 + "id": 31254296256412 }, "Name": "SC-Node(IsNull)", "Components": { @@ -3698,7 +3694,7 @@ }, { "Id": { - "id": 31072711844563 + "id": 31262886191004 }, "Name": "SC-Node(Start)", "Components": { @@ -3728,7 +3724,7 @@ }, { "Id": { - "id": 31064121909971 + "id": 31271476125596 }, "Name": "SC-Node(Once)", "Components": { @@ -3806,7 +3802,7 @@ }, { "Id": { - "id": 31141431321299 + "id": 31237116387228 }, "Name": "SC-Node(OrderedSequencer)", "Components": { @@ -4160,7 +4156,7 @@ }, { "Id": { - "id": 31051237008083 + "id": 31245706321820 }, "Name": "SC-Node(OrderedSequencer)", "Components": { @@ -4516,7 +4512,7 @@ "m_connections": [ { "Id": { - "id": 31167201125075 + "id": 31318720765852 }, "Name": "srcEndpoint=(On Graph Start: Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -4525,7 +4521,7 @@ "Id": 11968085700009090183, "sourceEndpoint": { "nodeId": { - "id": 31072711844563 + "id": 31262886191004 }, "slotId": { "m_id": "{E1417C09-E03B-4EA9-B9EC-67F8EC862B69}" @@ -4533,7 +4529,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -4544,7 +4540,7 @@ }, { "Id": { - "id": 31171496092371 + "id": 31323015733148 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(For Each: In)", "Components": { @@ -4553,7 +4549,7 @@ "Id": 14051685564799899080, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" @@ -4561,7 +4557,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31089891713747 + "id": 31284361027484 }, "slotId": { "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" @@ -4572,7 +4568,7 @@ }, { "Id": { - "id": 31175791059667 + "id": 31327310700444 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 1), destEndpoint=(And: In)", "Components": { @@ -4581,7 +4577,7 @@ "Id": 5835922357284603096, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{58EB3964-B87B-4C73-AD7B-532E4BBAD9E2}" @@ -4589,7 +4585,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31132841386707 + "id": 31228526452636 }, "slotId": { "m_id": "{FAFAB55A-69F1-495D-82FC-7D36F7842DA9}" @@ -4600,7 +4596,7 @@ }, { "Id": { - "id": 31180086026963 + "id": 31331605667740 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -4609,7 +4605,7 @@ "Id": 11349254841334591199, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" @@ -4617,7 +4613,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31085596746451 + "id": 31275771092892 }, "slotId": { "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" @@ -4628,7 +4624,7 @@ }, { "Id": { - "id": 31184380994259 + "id": 31335900635036 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 3), destEndpoint=(Is Null: In)", "Components": { @@ -4637,7 +4633,7 @@ "Id": 11724175899893098283, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" @@ -4645,7 +4641,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31046942040787 + "id": 31250001289116 }, "slotId": { "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" @@ -4656,7 +4652,7 @@ }, { "Id": { - "id": 31188675961555 + "id": 31340195602332 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 4), destEndpoint=(Or: In)", "Components": { @@ -4665,7 +4661,7 @@ "Id": 15445788857322783773, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{60D9FB27-2CAC-412A-8B3B-2E4B4574FD56}" @@ -4673,7 +4669,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31128546419411 + "id": 31211346583452 }, "slotId": { "m_id": "{C5E1B10E-FDFA-45F8-B6AF-BD9C672986FC}" @@ -4684,7 +4680,7 @@ }, { "Id": { - "id": 31192970928851 + "id": 31344490569628 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 5), destEndpoint=(Switch: In)", "Components": { @@ -4693,7 +4689,7 @@ "Id": 9877129165904558121, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" @@ -4701,7 +4697,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31158611190483 + "id": 31258591223708 }, "slotId": { "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" @@ -4712,7 +4708,7 @@ }, { "Id": { - "id": 31197265896147 + "id": 31348785536924 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 6), destEndpoint=(Not: In)", "Components": { @@ -4721,7 +4717,7 @@ "Id": 3561874480108576621, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{F71323EC-F182-465B-8671-C83BB07B227A}" @@ -4729,7 +4725,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31094186681043 + "id": 31280066060188 }, "slotId": { "m_id": "{120C810C-F84A-445F-82E1-FD06CD3AD9B7}" @@ -4740,7 +4736,7 @@ }, { "Id": { - "id": 31201560863443 + "id": 31353080504220 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 10), destEndpoint=(Add (+): In)", "Components": { @@ -4749,7 +4745,7 @@ "Id": 15711843380878163015, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{99CB5CB4-FF23-4C2B-9FBB-94D7752FCE80}" @@ -4757,7 +4753,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31124251452115 + "id": 31310130831260 }, "slotId": { "m_id": "{792F23CB-7356-4DCA-A186-69F2A0BBC063}" @@ -4768,7 +4764,7 @@ }, { "Id": { - "id": 31205855830739 + "id": 31357375471516 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 11), destEndpoint=(Math Expression: In)", "Components": { @@ -4777,7 +4773,7 @@ "Id": 10938060626218586852, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" @@ -4785,7 +4781,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31081301779155 + "id": 31241411354524 }, "slotId": { "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" @@ -4796,7 +4792,7 @@ }, { "Id": { - "id": 31210150798035 + "id": 31361670438812 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 12), destEndpoint=(IsZero: In)", "Components": { @@ -4805,7 +4801,7 @@ "Id": 7885809696299116611, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" @@ -4813,7 +4809,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31162906157779 + "id": 31207051616156 }, "slotId": { "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" @@ -4824,7 +4820,7 @@ }, { "Id": { - "id": 31214445765331 + "id": 31365965406108 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 13), destEndpoint=(Extract Properties: In)", "Components": { @@ -4833,7 +4829,7 @@ "Id": 4352059250555138202, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" @@ -4841,7 +4837,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31154316223187 + "id": 31232821419932 }, "slotId": { "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" @@ -4852,7 +4848,7 @@ }, { "Id": { - "id": 31218740732627 + "id": 31370260373404 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 14), destEndpoint=(Add (+): In)", "Components": { @@ -4861,7 +4857,7 @@ "Id": 4078469470815155794, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" @@ -4869,7 +4865,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31068416877267 + "id": 31267181158300 }, "slotId": { "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" @@ -4880,7 +4876,7 @@ }, { "Id": { - "id": 31223035699923 + "id": 31374555340700 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 15), destEndpoint=(Multiply (*): In)", "Components": { @@ -4889,7 +4885,7 @@ "Id": 17350434400301914971, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{7ECBB1CC-6F3A-442E-B063-2B143F26ECF0}" @@ -4897,7 +4893,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31115661517523 + "id": 31215641550748 }, "slotId": { "m_id": "{2D2F75D9-A1FB-4D70-86EF-8518E119DB07}" @@ -4908,7 +4904,7 @@ }, { "Id": { - "id": 31227330667219 + "id": 31378850307996 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 14), destEndpoint=(Add (+): In)", "Components": { @@ -4917,7 +4913,7 @@ "Id": 2124314791740833510, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{119F60AD-CF01-4F6D-AC9D-F76ED05EF408}" @@ -4925,7 +4921,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31077006811859 + "id": 31305835863964 }, "slotId": { "m_id": "{CDEA58A6-1B59-4476-B26E-0D5A828F35C7}" @@ -4936,7 +4932,7 @@ }, { "Id": { - "id": 31231625634515 + "id": 31383145275292 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(For Each: In)", "Components": { @@ -4945,7 +4941,7 @@ "Id": 14483355239609043570, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{E69D1672-B443-49D2-8228-9D45F4A4398C}" @@ -4953,7 +4949,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31145726288595 + "id": 31224231485340 }, "slotId": { "m_id": "{A9E6B254-446D-492F-B2CF-929CDC04ABFF}" @@ -4964,7 +4960,7 @@ }, { "Id": { - "id": 31235920601811 + "id": 31387440242588 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -4973,7 +4969,7 @@ "Id": 4849582226410181010, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{E965D8DB-1EDF-4CB2-910E-6782A6DD8487}" @@ -4981,7 +4977,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31107071582931 + "id": 31292950962076 }, "slotId": { "m_id": "{E4E25252-6AE7-4A4F-A175-50B9C6CD5DAE}" @@ -4992,7 +4988,7 @@ }, { "Id": { - "id": 31240215569107 + "id": 31391735209884 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 13), destEndpoint=(Extract Properties: In)", "Components": { @@ -5001,7 +4997,7 @@ "Id": 16660742051689195679, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{6552891F-4D35-4B2F-AE7D-B6CCE77B6966}" @@ -5009,7 +5005,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31150021255891 + "id": 31301540896668 }, "slotId": { "m_id": "{EADFB5B4-ADE0-4935-A102-99F8EC0C711A}" @@ -5020,7 +5016,7 @@ }, { "Id": { - "id": 31244510536403 + "id": 31396030177180 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 11), destEndpoint=(Math Expression: In)", "Components": { @@ -5029,7 +5025,7 @@ "Id": 761902755754097552, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{2A550F0A-D5D2-497A-AFF2-EBB330F29A4D}" @@ -5037,7 +5033,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31055531975379 + "id": 31219936518044 }, "slotId": { "m_id": "{6F8E4206-72C6-40E6-8AC1-205AA2C04804}" @@ -5048,7 +5044,7 @@ }, { "Id": { - "id": 31248805503699 + "id": 31400325144476 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 3), destEndpoint=(Is Null: In)", "Components": { @@ -5057,7 +5053,7 @@ "Id": 11478294740641420074, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{786CF87F-5153-44CE-A995-59CAAA0ED040}" @@ -5065,7 +5061,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31111366550227 + "id": 31254296256412 }, "slotId": { "m_id": "{2215C7E1-3EA3-4487-BA74-0A5628424CEA}" @@ -5076,7 +5072,7 @@ }, { "Id": { - "id": 31253100470995 + "id": 31404620111772 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 12), destEndpoint=(IsZero: In)", "Components": { @@ -5085,7 +5081,7 @@ "Id": 6172045094798670980, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{FBD12806-F42E-4896-A44D-E0E34C8977BF}" @@ -5093,7 +5089,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31137136354003 + "id": 31198461681564 }, "slotId": { "m_id": "{048F79E8-478C-46A1-AF3F-0B578022240D}" @@ -5104,7 +5100,7 @@ }, { "Id": { - "id": 31257395438291 + "id": 31408915079068 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 5), destEndpoint=(Switch: In)", "Components": { @@ -5113,7 +5109,7 @@ "Id": 10417773454009289241, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{CBD2A485-2FF1-405A-9940-E4268ED8EEC0}" @@ -5121,7 +5117,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31102776615635 + "id": 31297245929372 }, "slotId": { "m_id": "{52F5A723-7921-4644-AB19-5DCB94B51494}" @@ -5132,7 +5128,7 @@ }, { "Id": { - "id": 31261690405587 + "id": 31413210046364 }, "Name": "srcEndpoint=(For Each: Each), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5141,7 +5137,7 @@ "Id": 4836133045899771729, "sourceEndpoint": { "nodeId": { - "id": 31089891713747 + "id": 31284361027484 }, "slotId": { "m_id": "{8A4B7BED-4921-4C08-B35B-56D129A630E9}" @@ -5149,7 +5145,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5160,7 +5156,7 @@ }, { "Id": { - "id": 31265985372883 + "id": 31417505013660 }, "Name": "srcEndpoint=(For Each: Finished), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5169,7 +5165,7 @@ "Id": 6237489035629954338, "sourceEndpoint": { "nodeId": { - "id": 31089891713747 + "id": 31284361027484 }, "slotId": { "m_id": "{0DEFFE74-9D9C-4E18-AFA2-12B1657F7D1D}" @@ -5177,7 +5173,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5188,7 +5184,7 @@ }, { "Id": { - "id": 31270280340179 + "id": 31421799980956 }, "Name": "srcEndpoint=(And: True), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5197,7 +5193,7 @@ "Id": 4927775769680604779, "sourceEndpoint": { "nodeId": { - "id": 31132841386707 + "id": 31228526452636 }, "slotId": { "m_id": "{5BDD309F-0047-43E9-A911-475E47A036EC}" @@ -5205,7 +5201,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5216,7 +5212,7 @@ }, { "Id": { - "id": 31274575307475 + "id": 31426094948252 }, "Name": "srcEndpoint=(And: False), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5225,7 +5221,7 @@ "Id": 12544845157105431583, "sourceEndpoint": { "nodeId": { - "id": 31132841386707 + "id": 31228526452636 }, "slotId": { "m_id": "{7438C80C-9044-442D-8C71-827AB7DC3F0B}" @@ -5233,7 +5229,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5244,7 +5240,7 @@ }, { "Id": { - "id": 31278870274771 + "id": 31430389915548 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 0), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5253,7 +5249,7 @@ "Id": 13496863929205474320, "sourceEndpoint": { "nodeId": { - "id": 31085596746451 + "id": 31275771092892 }, "slotId": { "m_id": "{425822FB-C61E-4493-98C3-3A05418BD029}" @@ -5261,7 +5257,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5272,7 +5268,7 @@ }, { "Id": { - "id": 31283165242067 + "id": 31434684882844 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 1), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5281,7 +5277,7 @@ "Id": 12523441803443343729, "sourceEndpoint": { "nodeId": { - "id": 31085596746451 + "id": 31275771092892 }, "slotId": { "m_id": "{8FDC2E61-37AE-4E0F-82FE-7A4D9696123C}" @@ -5289,7 +5285,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5300,7 +5296,7 @@ }, { "Id": { - "id": 31287460209363 + "id": 31438979850140 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 2), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5309,7 +5305,7 @@ "Id": 4247029149608940629, "sourceEndpoint": { "nodeId": { - "id": 31085596746451 + "id": 31275771092892 }, "slotId": { "m_id": "{1000AB91-55FB-4615-B0EE-306816CFE895}" @@ -5317,7 +5313,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5328,7 +5324,7 @@ }, { "Id": { - "id": 31291755176659 + "id": 31443274817436 }, "Name": "srcEndpoint=(Is Null: True), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5337,7 +5333,7 @@ "Id": 2748837971044280491, "sourceEndpoint": { "nodeId": { - "id": 31046942040787 + "id": 31250001289116 }, "slotId": { "m_id": "{AA375295-D5E8-473C-A073-08A2853E750E}" @@ -5345,7 +5341,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5356,7 +5352,7 @@ }, { "Id": { - "id": 31296050143955 + "id": 31447569784732 }, "Name": "srcEndpoint=(Is Null: False), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5365,7 +5361,7 @@ "Id": 2379529025270594940, "sourceEndpoint": { "nodeId": { - "id": 31046942040787 + "id": 31250001289116 }, "slotId": { "m_id": "{342C520C-CA78-4261-91C9-629978B79BA3}" @@ -5373,7 +5369,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5384,7 +5380,7 @@ }, { "Id": { - "id": 31300345111251 + "id": 31451864752028 }, "Name": "srcEndpoint=(Or: True), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5393,7 +5389,7 @@ "Id": 4662929964571753389, "sourceEndpoint": { "nodeId": { - "id": 31128546419411 + "id": 31211346583452 }, "slotId": { "m_id": "{7FED3519-4670-4B3D-B81F-44393C2D7787}" @@ -5401,7 +5397,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5412,7 +5408,7 @@ }, { "Id": { - "id": 31304640078547 + "id": 31456159719324 }, "Name": "srcEndpoint=(Or: False), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5421,7 +5417,7 @@ "Id": 10410455197671109469, "sourceEndpoint": { "nodeId": { - "id": 31128546419411 + "id": 31211346583452 }, "slotId": { "m_id": "{E2D1192C-902D-4C82-9DE4-BBC20B31A54B}" @@ -5429,7 +5425,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5440,7 +5436,7 @@ }, { "Id": { - "id": 31308935045843 + "id": 31460454686620 }, "Name": "srcEndpoint=(Switch: Out 0), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5449,7 +5445,7 @@ "Id": 10099436517331803126, "sourceEndpoint": { "nodeId": { - "id": 31158611190483 + "id": 31258591223708 }, "slotId": { "m_id": "{800E14B1-C788-4C7F-B4D4-76121DE547C9}" @@ -5457,7 +5453,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5468,7 +5464,7 @@ }, { "Id": { - "id": 31313230013139 + "id": 31464749653916 }, "Name": "srcEndpoint=(Switch: Out 1), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5477,7 +5473,7 @@ "Id": 11535766430360773447, "sourceEndpoint": { "nodeId": { - "id": 31158611190483 + "id": 31258591223708 }, "slotId": { "m_id": "{9828EDD9-2689-424C-9708-304D720B1348}" @@ -5485,7 +5481,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5496,7 +5492,7 @@ }, { "Id": { - "id": 31317524980435 + "id": 31469044621212 }, "Name": "srcEndpoint=(Switch: Out 2), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5505,7 +5501,7 @@ "Id": 3612784336888322174, "sourceEndpoint": { "nodeId": { - "id": 31158611190483 + "id": 31258591223708 }, "slotId": { "m_id": "{4A1E25C6-E63B-4BC0-BBDE-533CA69C91C5}" @@ -5513,7 +5509,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5524,7 +5520,7 @@ }, { "Id": { - "id": 31321819947731 + "id": 31473339588508 }, "Name": "srcEndpoint=(Not: True), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5533,7 +5529,7 @@ "Id": 4611790098876313333, "sourceEndpoint": { "nodeId": { - "id": 31094186681043 + "id": 31280066060188 }, "slotId": { "m_id": "{6E82DFA3-70F4-419F-9971-AD243313E8D9}" @@ -5541,7 +5537,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5552,7 +5548,7 @@ }, { "Id": { - "id": 31326114915027 + "id": 31477634555804 }, "Name": "srcEndpoint=(Not: False), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5561,7 +5557,7 @@ "Id": 3740076693359624525, "sourceEndpoint": { "nodeId": { - "id": 31094186681043 + "id": 31280066060188 }, "slotId": { "m_id": "{5C53A008-E808-4D00-A4EC-AC6A0EFDAFB9}" @@ -5569,7 +5565,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5580,7 +5576,7 @@ }, { "Id": { - "id": 31330409882323 + "id": 31481929523100 }, "Name": "srcEndpoint=(Add (+): Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5589,7 +5585,7 @@ "Id": 3850851395875718062, "sourceEndpoint": { "nodeId": { - "id": 31124251452115 + "id": 31310130831260 }, "slotId": { "m_id": "{775F77BE-A9EC-455D-B378-15D16A0BEA4F}" @@ -5597,7 +5593,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5608,7 +5604,7 @@ }, { "Id": { - "id": 31334704849619 + "id": 31486224490396 }, "Name": "srcEndpoint=(Math Expression: Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5617,7 +5613,7 @@ "Id": 3602036390975897875, "sourceEndpoint": { "nodeId": { - "id": 31081301779155 + "id": 31241411354524 }, "slotId": { "m_id": "{5E038FBC-9A4B-489C-AB3E-26F103B7102E}" @@ -5625,7 +5621,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5636,7 +5632,7 @@ }, { "Id": { - "id": 31338999816915 + "id": 31490519457692 }, "Name": "srcEndpoint=(IsZero: Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5645,7 +5641,7 @@ "Id": 17614443468886602012, "sourceEndpoint": { "nodeId": { - "id": 31162906157779 + "id": 31207051616156 }, "slotId": { "m_id": "{2CD5D252-4872-41A2-9C9E-4B81AD9877B7}" @@ -5653,7 +5649,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5664,7 +5660,7 @@ }, { "Id": { - "id": 31343294784211 + "id": 31494814424988 }, "Name": "srcEndpoint=(Extract Properties: Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5673,7 +5669,7 @@ "Id": 4800366554066352627, "sourceEndpoint": { "nodeId": { - "id": 31154316223187 + "id": 31232821419932 }, "slotId": { "m_id": "{AC7594DE-A7F0-4519-9E07-0350AEEB25E0}" @@ -5681,7 +5677,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5692,7 +5688,7 @@ }, { "Id": { - "id": 31347589751507 + "id": 31499109392284 }, "Name": "srcEndpoint=(Add (+): Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5701,7 +5697,7 @@ "Id": 15231344167676276156, "sourceEndpoint": { "nodeId": { - "id": 31068416877267 + "id": 31267181158300 }, "slotId": { "m_id": "{5E66E5C1-AE26-4919-BFD7-66EC6DE9B7BB}" @@ -5709,7 +5705,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5720,7 +5716,7 @@ }, { "Id": { - "id": 31351884718803 + "id": 31503404359580 }, "Name": "srcEndpoint=(Multiply (*): Out), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5729,7 +5725,7 @@ "Id": 13866431563723516549, "sourceEndpoint": { "nodeId": { - "id": 31115661517523 + "id": 31215641550748 }, "slotId": { "m_id": "{7A580403-C074-4DAD-A65E-BF928EF19DC8}" @@ -5737,7 +5733,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5748,7 +5744,7 @@ }, { "Id": { - "id": 31356179686099 + "id": 31507699326876 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 16), destEndpoint=(TickBus Handler: Connect)", "Components": { @@ -5757,7 +5753,7 @@ "Id": 4065717098596350153, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{8BC13109-B3A3-4931-8E54-0DFC6383A274}" @@ -5765,7 +5761,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31119956484819 + "id": 31314425798556 }, "slotId": { "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" @@ -5776,7 +5772,7 @@ }, { "Id": { - "id": 31360474653395 + "id": 31511994294172 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 17), destEndpoint=(TickBus Handler: Disconnect)", "Components": { @@ -5785,7 +5781,7 @@ "Id": 451545062627990235, "sourceEndpoint": { "nodeId": { - "id": 31051237008083 + "id": 31245706321820 }, "slotId": { "m_id": "{3ED549E3-C72F-4EC5-8CD6-2B8A36A8E503}" @@ -5793,7 +5789,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31119956484819 + "id": 31314425798556 }, "slotId": { "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" @@ -5804,7 +5800,7 @@ }, { "Id": { - "id": 31364769620691 + "id": 31516289261468 }, "Name": "srcEndpoint=(TickBus Handler: OnConnected), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5813,7 +5809,7 @@ "Id": 16416933153170812903, "sourceEndpoint": { "nodeId": { - "id": 31119956484819 + "id": 31314425798556 }, "slotId": { "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" @@ -5821,7 +5817,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5832,7 +5828,7 @@ }, { "Id": { - "id": 31369064587987 + "id": 31520584228764 }, "Name": "srcEndpoint=(TickBus Handler: OnDisconnected), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5841,7 +5837,7 @@ "Id": 16427931620012509498, "sourceEndpoint": { "nodeId": { - "id": 31119956484819 + "id": 31314425798556 }, "slotId": { "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" @@ -5849,7 +5845,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5860,7 +5856,7 @@ }, { "Id": { - "id": 31373359555283 + "id": 31524879196060 }, "Name": "srcEndpoint=(TickBus Handler: ExecutionSlot:OnTick), destEndpoint=(Ordered Sequencer: In)", "Components": { @@ -5869,7 +5865,7 @@ "Id": 12537264777285639380, "sourceEndpoint": { "nodeId": { - "id": 31119956484819 + "id": 31314425798556 }, "slotId": { "m_id": "{99FA955C-7E6E-4539-85B0-16CBFBB1F0E3}" @@ -5877,7 +5873,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{06EAF2BD-2430-46D2-A19F-6E785B06A1B2}" @@ -5888,7 +5884,7 @@ }, { "Id": { - "id": 31377654522579 + "id": 31529174163356 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 16), destEndpoint=(TickBus Handler: Connect)", "Components": { @@ -5897,7 +5893,7 @@ "Id": 4140744289594349719, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{58AAA7C2-843B-4B0A-8451-B509284BFC6B}" @@ -5905,7 +5901,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31059826942675 + "id": 31288655994780 }, "slotId": { "m_id": "{C189EE08-DC89-4AF2-88BC-B564F84F28A6}" @@ -5916,7 +5912,7 @@ }, { "Id": { - "id": 31381949489875 + "id": 31533469130652 }, "Name": "srcEndpoint=(Ordered Sequencer: Out 17), destEndpoint=(TickBus Handler: Disconnect)", "Components": { @@ -5925,7 +5921,7 @@ "Id": 6223827301708831635, "sourceEndpoint": { "nodeId": { - "id": 31141431321299 + "id": 31237116387228 }, "slotId": { "m_id": "{C6B341C5-8F1F-4F38-96B1-07873BC03493}" @@ -5933,7 +5929,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31059826942675 + "id": 31288655994780 }, "slotId": { "m_id": "{10BB0A14-C955-464E-8745-7FBC88E24049}" @@ -5944,7 +5940,7 @@ }, { "Id": { - "id": 31386244457171 + "id": 31537764097948 }, "Name": "srcEndpoint=(TickBus Handler: OnConnected), destEndpoint=(Once: In)", "Components": { @@ -5953,7 +5949,7 @@ "Id": 16328568633919858732, "sourceEndpoint": { "nodeId": { - "id": 31059826942675 + "id": 31288655994780 }, "slotId": { "m_id": "{A7026536-ED61-48CA-8329-601DACF8A178}" @@ -5961,7 +5957,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31064121909971 + "id": 31271476125596 }, "slotId": { "m_id": "{67E7AF1F-F028-4460-819A-3FA6B9135F7B}" @@ -5972,7 +5968,7 @@ }, { "Id": { - "id": 31390539424467 + "id": 31542059065244 }, "Name": "srcEndpoint=(TickBus Handler: OnDisconnected), destEndpoint=(Once: In)", "Components": { @@ -5981,7 +5977,7 @@ "Id": 5193640857027050517, "sourceEndpoint": { "nodeId": { - "id": 31059826942675 + "id": 31288655994780 }, "slotId": { "m_id": "{95E02974-9E1C-407C-94DA-087C5B4EC55C}" @@ -5989,7 +5985,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31064121909971 + "id": 31271476125596 }, "slotId": { "m_id": "{67E7AF1F-F028-4460-819A-3FA6B9135F7B}" @@ -6000,7 +5996,7 @@ }, { "Id": { - "id": 31394834391763 + "id": 31546354032540 }, "Name": "srcEndpoint=(Once: Out), destEndpoint=(Mark Complete: In)", "Components": { @@ -6009,7 +6005,7 @@ "Id": 5213414421933364896, "sourceEndpoint": { "nodeId": { - "id": 31064121909971 + "id": 31271476125596 }, "slotId": { "m_id": "{922907EE-9B7C-49CF-80A2-0A9FF5CDCB8C}" @@ -6017,7 +6013,7 @@ }, "targetEndpoint": { "nodeId": { - "id": 31098481648339 + "id": 31202756648860 }, "slotId": { "m_id": "{79C2ABDD-F20A-4042-BF5C-8C09DC9332C7}" @@ -6037,7 +6033,7 @@ "GraphCanvasData": [ { "Key": { - "id": 31042647073491 + "id": 31194166714268 }, "Value": { "ComponentData": { @@ -6054,7 +6050,97 @@ }, { "Key": { - "id": 31046942040787 + "id": 31198461681564 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 3260.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{810D332E-6C30-437C-9BCA-DF663A237034}" + } + } + } + }, + { + "Key": { + "id": 31202756648860 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TestingNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2640.0, + 4320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{90DEA5B5-B658-4163-964E-91DB8D0D0F91}" + } + } + } + }, + { + "Key": { + "id": 31207051616156 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{AE920511-0E26-4EEF-ADAD-982BEA59BA94}" + } + } + } + }, + { + "Key": { + "id": 31211346583452 }, "Value": { "ComponentData": { @@ -6069,7 +6155,7 @@ "$type": "GeometrySaveData", "Position": [ 300.0, - 1240.0 + 1460.0 ] }, "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { @@ -6077,14 +6163,14 @@ }, "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { "$type": "PersistentIdComponentSaveData", - "PersistentId": "{63DF2982-B424-4D30-BF05-9DA9DD5664EC}" + "PersistentId": "{0C7217EF-A630-46C6-A1C8-D4202697B60E}" } } } }, { "Key": { - "id": 31051237008083 + "id": 31215641550748 }, "Value": { "ComponentData": { @@ -6093,13 +6179,13 @@ }, "{328FF15C-C302-458F-A43D-E1794DE0904E}": { "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" + "PaletteOverride": "MathNodeTitlePalette" }, "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { "$type": "GeometrySaveData", "Position": [ - -480.0, - 2320.0 + 300.0, + 4020.0 ] }, "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { @@ -6107,14 +6193,14 @@ }, "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { "$type": "PersistentIdComponentSaveData", - "PersistentId": "{AC1D06EF-C967-4F35-95BD-8D822F4A2CE7}" + "PersistentId": "{E6E72236-4B7B-47AD-ABF9-08E0D1691F72}" } } } }, { "Key": { - "id": 31055531975379 + "id": 31219936518044 }, "Value": { "ComponentData": { @@ -6144,7 +6230,457 @@ }, { "Key": { - "id": 31059826942675 + "id": 31224231485340 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 340.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{EDABFAD6-F9B5-4490-8EC6-165291FF3588}" + } + } + } + }, + { + "Key": { + "id": 31228526452636 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 700.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{F60EF486-6C8B-4943-B3F4-600F8148DE78}" + } + } + } + }, + { + "Key": { + "id": 31232821419932 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3580.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{BB3891CA-9936-4F18-8552-8EB7F2D02206}" + } + } + } + }, + { + "Key": { + "id": 31237116387228 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 1200.0, + 2660.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{05F42C5B-4887-4800-8422-D5E5C1361E5F}" + } + } + } + }, + { + "Key": { + "id": 31241411354524 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3040.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{32F17925-C934-4CC7-918A-3026954CABD6}" + } + } + } + }, + { + "Key": { + "id": 31245706321820 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -480.0, + 2320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{AC1D06EF-C967-4F35-95BD-8D822F4A2CE7}" + } + } + } + }, + { + "Key": { + "id": 31250001289116 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 1240.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{63DF2982-B424-4D30-BF05-9DA9DD5664EC}" + } + } + } + }, + { + "Key": { + "id": 31254296256412 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2040.0, + 1180.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{9952383B-0B57-43BB-B59C-501C3F2CDE30}" + } + } + } + }, + { + "Key": { + "id": 31258591223708 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 1740.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{E6746414-838B-4AF7-AC50-EBEB0D2C06C2}" + } + } + } + }, + { + "Key": { + "id": 31262886191004 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "TimeNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + -900.0, + 2400.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{D3649B82-A382-47A3-8168-BC7BA0377449}" + } + } + } + }, + { + "Key": { + "id": 31267181158300 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "MathNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 3780.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{D305A28C-D38B-4A34-BEA1-7E7AA92B853A}" + } + } + } + }, + { + "Key": { + "id": 31271476125596 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 2420.0, + 4320.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{0CC6067B-5802-4AB3-9FF4-C1DF2C283DBB}" + } + } + } + }, + { + "Key": { + "id": 31275771092892 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 960.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{55307FED-8C26-4EC5-98B5-F080C79E784D}" + } + } + } + }, + { + "Key": { + "id": 31280066060188 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "LogicNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 2000.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{5E0AD895-3D93-41F0-86D0-0A9DC4305145}" + } + } + } + }, + { + "Key": { + "id": 31284361027484 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{328FF15C-C302-458F-A43D-E1794DE0904E}": { + "$type": "GeneralNodeTitleComponentSaveData", + "PaletteOverride": "DefaultNodeTitlePalette" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 300.0, + 400.0 + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{F37ED565-54EF-4A7C-9FB4-ABA1A71A4A36}" + } + } + } + }, + { + "Key": { + "id": 31288655994780 }, "Value": { "ComponentData": { @@ -6179,307 +6715,7 @@ }, { "Key": { - "id": 31064121909971 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2420.0, - 4320.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{0CC6067B-5802-4AB3-9FF4-C1DF2C283DBB}" - } - } - } - }, - { - "Key": { - "id": 31068416877267 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 3780.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{D305A28C-D38B-4A34-BEA1-7E7AA92B853A}" - } - } - } - }, - { - "Key": { - "id": 31072711844563 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "TimeNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - -900.0, - 2400.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{D3649B82-A382-47A3-8168-BC7BA0377449}" - } - } - } - }, - { - "Key": { - "id": 31077006811859 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2040.0, - 3720.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{ABCB6F4F-5683-4958-B544-E543B5591129}" - } - } - } - }, - { - "Key": { - "id": 31081301779155 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 3040.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{32F17925-C934-4CC7-918A-3026954CABD6}" - } - } - } - }, - { - "Key": { - "id": 31085596746451 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 960.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{55307FED-8C26-4EC5-98B5-F080C79E784D}" - } - } - } - }, - { - "Key": { - "id": 31089891713747 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "DefaultNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 400.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{F37ED565-54EF-4A7C-9FB4-ABA1A71A4A36}" - } - } - } - }, - { - "Key": { - "id": 31094186681043 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 2000.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{5E0AD895-3D93-41F0-86D0-0A9DC4305145}" - } - } - } - }, - { - "Key": { - "id": 31098481648339 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "TestingNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2640.0, - 4320.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{90DEA5B5-B658-4163-964E-91DB8D0D0F91}" - } - } - } - }, - { - "Key": { - "id": 31102776615635 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2040.0, - 1680.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{E6DB84DC-F8BE-4C8E-BE0D-A0B96652B2C0}" - } - } - } - }, - { - "Key": { - "id": 31107071582931 + "id": 31292950962076 }, "Value": { "ComponentData": { @@ -6509,7 +6745,7 @@ }, { "Key": { - "id": 31111366550227 + "id": 31297245929372 }, "Value": { "ComponentData": { @@ -6524,7 +6760,7 @@ "$type": "GeometrySaveData", "Position": [ 2040.0, - 1180.0 + 1680.0 ] }, "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { @@ -6532,259 +6768,14 @@ }, "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { "$type": "PersistentIdComponentSaveData", - "PersistentId": "{9952383B-0B57-43BB-B59C-501C3F2CDE30}" + "PersistentId": "{E6DB84DC-F8BE-4C8E-BE0D-A0B96652B2C0}" } } } }, { "Key": { - "id": 31115661517523 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 4020.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{E6E72236-4B7B-47AD-ABF9-08E0D1691F72}" - } - } - } - }, - { - "Key": { - "id": 31119956484819 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 340.0, - 4320.0 - ] - }, - "{9E81C95F-89C0-4476-8E82-63CCC4E52E04}": { - "$type": "EBusHandlerNodeDescriptorSaveData", - "DisplayConnections": true, - "EventIds": [ - { - "Value": 1502188240 - } - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{3B6A148E-D130-4461-BA4D-EF0C91E7B729}" - } - } - } - }, - { - "Key": { - "id": 31124251452115 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 2820.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{0F538778-0124-48B9-B8D8-DB50D3620953}" - } - } - } - }, - { - "Key": { - "id": 31128546419411 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 1460.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{0C7217EF-A630-46C6-A1C8-D4202697B60E}" - } - } - } - }, - { - "Key": { - "id": 31132841386707 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 700.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{F60EF486-6C8B-4943-B3F4-600F8148DE78}" - } - } - } - }, - { - "Key": { - "id": 31137136354003 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "MathNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2040.0, - 3260.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{810D332E-6C30-437C-9BCA-DF663A237034}" - } - } - } - }, - { - "Key": { - "id": 31141431321299 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 1200.0, - 2660.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{05F42C5B-4887-4800-8422-D5E5C1361E5F}" - } - } - } - }, - { - "Key": { - "id": 31145726288595 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "DefaultNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 2040.0, - 340.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{EDABFAD6-F9B5-4490-8EC6-165291FF3588}" - } - } - } - }, - { - "Key": { - "id": 31150021255891 + "id": 31301540896668 }, "Value": { "ComponentData": { @@ -6814,7 +6805,7 @@ }, { "Key": { - "id": 31154316223187 + "id": 31305835863964 }, "Value": { "ComponentData": { @@ -6823,13 +6814,13 @@ }, "{328FF15C-C302-458F-A43D-E1794DE0904E}": { "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "DefaultNodeTitlePalette" + "PaletteOverride": "MathNodeTitlePalette" }, "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { "$type": "GeometrySaveData", "Position": [ - 300.0, - 3580.0 + 2040.0, + 3720.0 ] }, "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { @@ -6837,44 +6828,14 @@ }, "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { "$type": "PersistentIdComponentSaveData", - "PersistentId": "{BB3891CA-9936-4F18-8552-8EB7F2D02206}" + "PersistentId": "{ABCB6F4F-5683-4958-B544-E543B5591129}" } } } }, { "Key": { - "id": 31158611190483 - }, - "Value": { - "ComponentData": { - "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { - "$type": "NodeSaveData" - }, - "{328FF15C-C302-458F-A43D-E1794DE0904E}": { - "$type": "GeneralNodeTitleComponentSaveData", - "PaletteOverride": "LogicNodeTitlePalette" - }, - "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { - "$type": "GeometrySaveData", - "Position": [ - 300.0, - 1740.0 - ] - }, - "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { - "$type": "StylingComponentSaveData" - }, - "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { - "$type": "PersistentIdComponentSaveData", - "PersistentId": "{E6746414-838B-4AF7-AC50-EBEB0D2C06C2}" - } - } - } - }, - { - "Key": { - "id": 31162906157779 + "id": 31310130831260 }, "Value": { "ComponentData": { @@ -6889,7 +6850,7 @@ "$type": "GeometrySaveData", "Position": [ 300.0, - 3320.0 + 2820.0 ] }, "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { @@ -6897,7 +6858,42 @@ }, "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { "$type": "PersistentIdComponentSaveData", - "PersistentId": "{AE920511-0E26-4EEF-ADAD-982BEA59BA94}" + "PersistentId": "{0F538778-0124-48B9-B8D8-DB50D3620953}" + } + } + } + }, + { + "Key": { + "id": 31314425798556 + }, + "Value": { + "ComponentData": { + "{24CB38BB-1705-4EC5-8F63-B574571B4DCD}": { + "$type": "NodeSaveData" + }, + "{7CC444B1-F9B3-41B5-841B-0C4F2179F111}": { + "$type": "GeometrySaveData", + "Position": [ + 340.0, + 4320.0 + ] + }, + "{9E81C95F-89C0-4476-8E82-63CCC4E52E04}": { + "$type": "EBusHandlerNodeDescriptorSaveData", + "DisplayConnections": true, + "EventIds": [ + { + "Value": 1502188240 + } + ] + }, + "{B0B99C8A-03AF-4CF6-A926-F65C874C3D97}": { + "$type": "StylingComponentSaveData" + }, + "{B1F49A35-8408-40DA-B79E-F1E3B64322CE}": { + "$type": "PersistentIdComponentSaveData", + "PersistentId": "{3B6A148E-D130-4461-BA4D-EF0C91E7B729}" } } } From 875918dedaddfe19a1edc8acc31cc698f490df7d Mon Sep 17 00:00:00 2001 From: Mikhail Naumov Date: Fri, 20 Aug 2021 18:10:30 -0700 Subject: [PATCH 15/27] Allowing prebas with missing components to load, and clarifying error message Signed-off-by: Mikhail Naumov --- .../AzCore/Component/EntitySerializer.cpp | 7 ++++++- .../Serialization/Json/JsonDeserializer.cpp | 20 ++++++++++++++++--- .../Prefab/PrefabDomUtils.cpp | 9 +++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp b/Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp index 16452be76d..64ba9b2c2c 100644 --- a/Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Component/EntitySerializer.cpp @@ -81,9 +81,14 @@ namespace AZ azrtti_typeid(), inputValue, "Components", context); + static TypeId genericComponentWrapperTypeId("{68D358CA-89B9-4730-8BA6-E181DEA28FDE}"); for (auto& [componentKey, component] : componentMap) { - entityInstance->m_components.emplace_back(component); + // if underlying type is genericComponentWrapperTypeId, the template is null and the component should not be addded + if (component->GetUnderlyingComponentType() != genericComponentWrapperTypeId) + { + entityInstance->m_components.emplace_back(component); + } } result.Combine(componentLoadResult); diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 840034e52f..c1ffb774e8 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -571,9 +571,23 @@ namespace AZ if (loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine || loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds) { - AZStd::string_view message = loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds ? - "Unable to resolve provided type because the same name points to multiple types." : - "Unable to resolve provided type."; + AZStd::string message; + if (loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds) + { + message = "Unable to resolve provided type because the same name points to multiple types."; + } + else + { + auto typeField = pointerData.FindMember(JsonSerialization::TypeIdFieldIdentifier); + if (typeField != pointerData.MemberEnd() && typeField->value.IsString()) + { + message = AZStd::string::format("Unable to resolve provided type: %s.", typeField->value.GetString()); + } + else + { + message = "Unable to resolve provided type."; + } + } status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, message); return ResolvePointerResult::FullyProcessed; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp index dcc14d3b91..f60759f77e 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabDomUtils.cpp @@ -253,6 +253,15 @@ namespace AzToolsFramework settings.m_metadata.Add(&entityIdMapper); settings.m_metadata.Create(newlyAddedEntities); + AZStd::string scratchBuffer; + auto issueReportingCallback = [&scratchBuffer]( + AZStd::string_view message, AZ::JsonSerializationResult::ResultCode result, + AZStd::string_view path) -> AZ::JsonSerializationResult::ResultCode + { + return Internal::JsonIssueReporter(scratchBuffer, message, result, path); + }; + settings.m_reporting = AZStd::move(issueReportingCallback); + AZ::JsonSerializationResult::ResultCode result = AZ::JsonSerialization::Load(instance, prefabDom, settings); AZ::Data::AssetManager::Instance().ResumeAssetRelease(); From f224d657be4380bffe41c249c537f3f6b6e94415 Mon Sep 17 00:00:00 2001 From: Mikhail Naumov <82239319+AMZN-mnaumov@users.noreply.github.com> Date: Mon, 23 Aug 2021 13:01:37 -0700 Subject: [PATCH 16/27] Ronald's feedback Co-authored-by: AMZN-koppersr <82230785+AMZN-koppersr@users.noreply.github.com> Signed-off-by: Mikhail Naumov --- .../Serialization/Json/JsonDeserializer.cpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index c1ffb774e8..5f90744607 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -571,25 +571,23 @@ namespace AZ if (loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine || loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds) { - AZStd::string message; - if (loadedTypeId.m_determination == TypeIdDetermination::FailedDueToMultipleTypeIds) - { - message = "Unable to resolve provided type because the same name points to multiple types."; - } - else - { auto typeField = pointerData.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeField != pointerData.MemberEnd() && typeField->value.IsString()) { - message = AZStd::string::format("Unable to resolve provided type: %s.", typeField->value.GetString()); + const char* format = loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ? + "Unable to resolve provided type: %.*s." : + "Unable to resolve provided type %.*s because the same name points to multiple types."; + status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, + AZStd::string::format("Unable to resolve provided type: %.*s.", typeField->value.GetStringLength(), typeField->value.GetString())); } else { - message = "Unable to resolve provided type."; + const char* message = loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ? + "Unable to resolve provided type." : + "Unable to resolve provided type because the same name points to multiple types." + status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, "Unable to resolve provided type."); } - } - status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, message); - return ResolvePointerResult::FullyProcessed; + return ResolvePointerResult::FullyProcessed; } if (loadedTypeId.m_typeId != objectType) From f7eaa4490fd4dbcfe47d00ccd5101c5b092f6785 Mon Sep 17 00:00:00 2001 From: Mikhail Naumov Date: Mon, 23 Aug 2021 13:40:01 -0700 Subject: [PATCH 17/27] fixing syntax errors Signed-off-by: Mikhail Naumov --- .../AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp index 5f90744607..56c2b1666d 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonDeserializer.cpp @@ -578,14 +578,14 @@ namespace AZ "Unable to resolve provided type: %.*s." : "Unable to resolve provided type %.*s because the same name points to multiple types."; status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, - AZStd::string::format("Unable to resolve provided type: %.*s.", typeField->value.GetStringLength(), typeField->value.GetString())); + AZStd::string::format(format, typeField->value.GetStringLength(), typeField->value.GetString())); } else { const char* message = loadedTypeId.m_determination == TypeIdDetermination::FailedToDetermine ? "Unable to resolve provided type." : - "Unable to resolve provided type because the same name points to multiple types." - status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, "Unable to resolve provided type."); + "Unable to resolve provided type because the same name points to multiple types."; + status = context.Report(Tasks::RetrieveInfo, Outcomes::Unknown, message); } return ResolvePointerResult::FullyProcessed; } From 95a812b2380d45f2448a8fb451286cf755afd91c Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 23 Aug 2021 15:07:42 -0700 Subject: [PATCH 18/27] fixup codegen, remove android errors Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AutoGen/ScriptCanvasGrammar_Header.jinja | 10 ++++------ .../AutoGen/ScriptCanvasGrammar_Source.jinja | 8 +++----- .../AutoGen/ScriptCanvas_Macros.jinja | 19 ------------------- .../ScriptCanvas/Data/BehaviorContextObject.h | 9 +++++---- 4 files changed, 12 insertions(+), 34 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja index aec7f22344..ea87573306 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja @@ -44,11 +44,9 @@ namespace {{attribute_Namespace}} { {% endif %} {% set className = Class.attrib['Name'] %} -{% set baseClassPair = [] %} -{% if macros.CreateBaseClassVariables(Class, baseClassPair) %}{% endif %} -{% set baseClass = baseClassPair[0] %} -{% set baseClasses = baseClassPair[1] %} - +{% set bases = Class.attrib['Base'].split(';') if Class.attrib['Base'] is string else ["ScriptCanvas::Node", "ScriptCanvas::Node"] %} +{% set baseClass = bases[0] %} +{% set baseClasses = bases[1] if bases|length() > 1 else "ScriptCanvas::Node" %} ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //// @@ -68,7 +66,7 @@ namespace {{attribute_Namespace}} // You must #include the generated header into the source header #define SCRIPTCANVAS_NODE_{{ className }} \ public: \ - AZ_COMPONENT({{ className }}, "{{ classUuid }}", {{ baseClasses}} ); \ + AZ_COMPONENT({{ className }}, "{{ classUuid }}", {{ baseClasses }} ); \ static void Reflect(AZ::ReflectContext* reflection); \ void ConfigureSlots() override; \ bool RequiresDynamicSlotOrdering() const override; \ diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index 752ffd8bef..e206b185e0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -28,11 +28,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT #include "{{ xml.attrib['Include'] }}" {% for Class in xml.iter('Class') %} -{% set baseClassPair = [] %} -{% if macros.CreateBaseClassVariables(Class, baseClassPair) %}{% endif %} -{% set baseClass = baseClassPair[0] %} -{% set baseClasses = baseClassPair[1] %} - +{% set bases = Class.attrib['Base'].split(';') if Class.attrib['Base'] is string else ["ScriptCanvas::Node", "ScriptCanvas::Node"] %} +{% set baseClass = bases[0] %} +{% set baseClasses = bases[1] if bases|length() > 1 else "ScriptCanvas::Node" %} void {{ Class.attrib['QualifiedName'] }}::ConfigureSlots() { {{ baseClass }}::ConfigureSlots(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja index ee2100d3f6..0b9242bf3d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Macros.jinja @@ -173,25 +173,6 @@ AZStd::tuple<{{returnTypes|join(", ")}}> {# ------- #} -{# CreateBaseClassVariables #} -{# Creates "baseClass" and "baseClasses" variables to use when needed "baseClasses" is a comma separated list that in includes baseClass #} -{%- macro CreateBaseClassVariables(Class, baseClassPair) -%} -{% set baseAttrib = Class.attrib['Base'] %} -{% if baseAttrib is defined %} -{% if baseAttrib.split(';')|length > 1 %} -{% if baseClassPair.append(baseAttrib.split(';')[0]) %}{% endif %} -{% if baseClassPair.append(", ".join(baseAttrib.split(';'))) %}{% endif %} -{% else %} -{% if baseClassPair.append(baseAttrib) %}{% endif %} -{% if baseClassPair.append(baseAttrib) %}{% endif %} -{% endif %} -{% else %} -{% if baseClassPair.append("ScriptCanvas::Node") %}{% endif %} -{% if baseClassPair.append("ScriptCanvas::Node") %}{% endif %} -{% endif %} -{%- endmacro -%} -{# ------- #} - {# ------------------------------------------------------------------------------------- #} {# NODEABLES #} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index b2e282dbe2..b129a2b0dd 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -105,13 +105,14 @@ namespace ScriptCanvas // it is very important to track these from the moment they are created... friend struct AZ::Serialize::InstanceFactory; friend struct AZ::AnyTypeInfoConcept; + //...so don't use the ctors, use the Create functions... //...the friend declarations are here for compatibility with the serialization system only AZ_FORCE_INLINE BehaviorContextObject() = default; - BehaviorContextObject& operator=(const BehaviorContextObject&) = default; - BehaviorContextObject(const BehaviorContextObject&) = default; - BehaviorContextObject(BehaviorContextObject&&) = default; - BehaviorContextObject& operator=(BehaviorContextObject&& source) = default; + + BehaviorContextObject& operator=(const BehaviorContextObject&) = delete; + + BehaviorContextObject(const BehaviorContextObject&) = delete; // copy ctor AZ_FORCE_INLINE BehaviorContextObject(const void* source, const AnyTypeInfo& typeInfo, AZ::u32 flags); From 13188f89580da398c019043510d402bddd4bb9da Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 23 Aug 2021 15:56:45 -0700 Subject: [PATCH 19/27] Simplify codegen of baseclass Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja | 4 +--- .../ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja | 4 +--- .../ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja index ea87573306..ae531aed3b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Header.jinja @@ -44,9 +44,7 @@ namespace {{attribute_Namespace}} { {% endif %} {% set className = Class.attrib['Name'] %} -{% set bases = Class.attrib['Base'].split(';') if Class.attrib['Base'] is string else ["ScriptCanvas::Node", "ScriptCanvas::Node"] %} -{% set baseClass = bases[0] %} -{% set baseClasses = bases[1] if bases|length() > 1 else "ScriptCanvas::Node" %} +{% set baseClasses = ", ".join(Class.attrib['Base'].split(';')) if Class.attrib['Base'] is string else "ScriptCanvas::Node" %} ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////// //// diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja index e206b185e0..1db676df84 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasGrammar_Source.jinja @@ -28,9 +28,7 @@ SPDX-License-Identifier: Apache-2.0 OR MIT #include "{{ xml.attrib['Include'] }}" {% for Class in xml.iter('Class') %} -{% set bases = Class.attrib['Base'].split(';') if Class.attrib['Base'] is string else ["ScriptCanvas::Node", "ScriptCanvas::Node"] %} -{% set baseClass = bases[0] %} -{% set baseClasses = bases[1] if bases|length() > 1 else "ScriptCanvas::Node" %} +{% set baseClass = Class.attrib['Base'].split(';')[0] if Class.attrib['Base'] is string else "ScriptCanvas::Node" %} void {{ Class.attrib['QualifiedName'] }}::ConfigureSlots() { {{ baseClass }}::ConfigureSlots(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml index 53d8623fe8..4e2e89fc7b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Logic/Gate.ScriptCanvasGrammar.xml @@ -5,7 +5,6 @@ QualifiedName="ScriptCanvas::Nodes::Logic::Gate" PreferredClassName="If" Uuid="{F19CC10A-02FD-4E75-ADAA-9CFBD8A4E2F8}" - Base="ScriptCanvas::Node" Icon="Icons/ScriptCanvas/Print.png" Version="0" GeneratePropertyFriend="True" From eabd963e283d7c5cb061d1a9e701010e25899f3c Mon Sep 17 00:00:00 2001 From: evanchia Date: Mon, 23 Aug 2021 16:00:23 -0700 Subject: [PATCH 20/27] Fixed comment in remote console unit test Signed-off-by: evanchia --- .../tests/unit/test_remote_console_commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py b/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py index e0ac82eb99..9be0685874 100755 --- a/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py +++ b/Tools/RemoteConsole/ly_remote_console/tests/unit/test_remote_console_commands.py @@ -145,7 +145,7 @@ class TestRemoteConsole(): rc_instance = remote_console.RemoteConsole() rc_instance.on_display = mock.MagicMock() rc_instance.ready = mock.MagicMock() - msg = b'I0' # in python3 socket.recv returns byte array. 7 is AUTOCOMPLETELISTDONE + msg = b'I0' # in python3 socket.recv returns byte array. I is CONNECTMESSAGE rc_instance._handle_message(msg) From b820c36c80e64c3e81d3513a7fc913fce05a49e3 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Mon, 23 Aug 2021 16:17:10 -0700 Subject: [PATCH 21/27] clang is more specific where the modifier should be Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- .../Math/Internal/SimdMathCommon_simd.inl | 46 +++++++++---------- Code/Framework/AzCore/AzCore/Math/SimdMath.h | 36 +++++++-------- Code/Legacy/CryCommon/Cry_Camera.h | 2 +- 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl b/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl index 46bd071637..b27abf120f 100644 --- a/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl +++ b/Code/Framework/AzCore/AzCore/Math/Internal/SimdMathCommon_simd.inl @@ -12,29 +12,29 @@ namespace AZ { namespace Simd { - static constexpr alignas(16) float g_sinCoef1[4] = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f }; - static constexpr alignas(16) float g_sinCoef2[4] = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f }; - static constexpr alignas(16) float g_sinCoef3[4] = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f }; - static constexpr alignas(16) float g_cosCoef1[4] = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f }; - static constexpr alignas(16) float g_cosCoef2[4] = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f }; - static constexpr alignas(16) float g_cosCoef3[4] = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f }; - static constexpr alignas(16) float g_acosHiCoef1[4] = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f }; - static constexpr alignas(16) float g_acosHiCoef2[4] = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f }; - static constexpr alignas(16) float g_acosHiCoef3[4] = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f }; - static constexpr alignas(16) float g_acosHiCoef4[4] = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f }; - static constexpr alignas(16) float g_acosLoCoef1[4] = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f }; - static constexpr alignas(16) float g_acosLoCoef2[4] = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f }; - static constexpr alignas(16) float g_acosLoCoef3[4] = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f }; - static constexpr alignas(16) float g_acosLoCoef4[4] = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f }; - static constexpr alignas(16) float g_acosCoef1[4] = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f }; - static constexpr alignas(16) float g_acosCoef2[4] = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f }; - static constexpr alignas(16) float g_acosCoef3[4] = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f }; - static constexpr alignas(16) float g_atanHiRange[4] = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f }; - static constexpr alignas(16) float g_atanLoRange[4] = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f }; - static constexpr alignas(16) float g_atanCoef1[4] = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f }; - static constexpr alignas(16) float g_atanCoef2[4] = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f }; - static constexpr alignas(16) float g_atanCoef3[4] = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f }; - static constexpr alignas(16) float g_atanCoef4[4] = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f }; + alignas(16) static constexpr float g_sinCoef1[4] = { -0.0001950727f, -0.0001950727f, -0.0001950727f, -0.0001950727f }; + alignas(16) static constexpr float g_sinCoef2[4] = { 0.0083320758f, 0.0083320758f, 0.0083320758f, 0.0083320758f }; + alignas(16) static constexpr float g_sinCoef3[4] = { -0.1666665247f, -0.1666665247f, -0.1666665247f, -0.1666665247f }; + alignas(16) static constexpr float g_cosCoef1[4] = { -0.0013602249f, -0.0013602249f, -0.0013602249f, -0.0013602249f }; + alignas(16) static constexpr float g_cosCoef2[4] = { 0.0416566950f, 0.0416566950f, 0.0416566950f, 0.0416566950f }; + alignas(16) static constexpr float g_cosCoef3[4] = { -0.4999990225f, -0.4999990225f, -0.4999990225f, -0.4999990225f }; + alignas(16) static constexpr float g_acosHiCoef1[4] = { -0.0012624911f, -0.0012624911f, -0.0012624911f, -0.0012624911f }; + alignas(16) static constexpr float g_acosHiCoef2[4] = { 0.0066700901f, 0.0066700901f, 0.0066700901f, 0.0066700901f }; + alignas(16) static constexpr float g_acosHiCoef3[4] = { -0.0170881256f, -0.0170881256f, -0.0170881256f, -0.0170881256f }; + alignas(16) static constexpr float g_acosHiCoef4[4] = { 0.0308918810f, 0.0308918810f, 0.0308918810f, 0.0308918810f }; + alignas(16) static constexpr float g_acosLoCoef1[4] = { -0.0501743046f, -0.0501743046f, -0.0501743046f, -0.0501743046f }; + alignas(16) static constexpr float g_acosLoCoef2[4] = { 0.0889789874f, 0.0889789874f, 0.0889789874f, 0.0889789874f }; + alignas(16) static constexpr float g_acosLoCoef3[4] = { -0.2145988016f, -0.2145988016f, -0.2145988016f, -0.2145988016f }; + alignas(16) static constexpr float g_acosLoCoef4[4] = { 1.5707963050f, 1.5707963050f, 1.5707963050f, 1.5707963050f }; + alignas(16) static constexpr float g_acosCoef1[4] = { -0.0200752200f, -0.0200752200f, -0.0200752200f, -0.0200752200f }; + alignas(16) static constexpr float g_acosCoef2[4] = { 0.0759031500f, 0.0759031500f, 0.0759031500f, 0.0759031500f }; + alignas(16) static constexpr float g_acosCoef3[4] = { -0.2126757000f, -0.2126757000f, -0.2126757000f, -0.2126757000f }; + alignas(16) static constexpr float g_atanHiRange[4] = { 2.4142135624f, 2.4142135624f, 2.4142135624f, 2.4142135624f }; + alignas(16) static constexpr float g_atanLoRange[4] = { 0.4142135624f, 0.4142135624f, 0.4142135624f, 0.4142135624f }; + alignas(16) static constexpr float g_atanCoef1[4] = { 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f, 8.05374449538e-2f }; + alignas(16) static constexpr float g_atanCoef2[4] = { -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f, -1.38776856032e-1f }; + alignas(16) static constexpr float g_atanCoef3[4] = { 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f, 1.99777106478e-1f }; + alignas(16) static constexpr float g_atanCoef4[4] = { -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f, -3.33329491539e-1f }; namespace Common { diff --git a/Code/Framework/AzCore/AzCore/Math/SimdMath.h b/Code/Framework/AzCore/AzCore/Math/SimdMath.h index 3d07cd41e8..0c14ed1eaa 100644 --- a/Code/Framework/AzCore/AzCore/Math/SimdMath.h +++ b/Code/Framework/AzCore/AzCore/Math/SimdMath.h @@ -24,24 +24,24 @@ namespace AZ { namespace Simd { - static constexpr alignas(16) float g_vec1111[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - static constexpr alignas(16) float g_vec1000[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; - static constexpr alignas(16) float g_vec0100[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; - static constexpr alignas(16) float g_vec0010[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; - static constexpr alignas(16) float g_vec0001[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; - static constexpr alignas(16) float g_Pi[4] = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi }; - static constexpr alignas(16) float g_TwoPi[4] = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi }; - static constexpr alignas(16) float g_HalfPi[4] = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi }; - static constexpr alignas(16) float g_QuarterPi[4] = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi }; - static constexpr alignas(16) float g_TwoOverPi[4] = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi }; - static constexpr alignas(16) int32_t g_absMask[4] = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff }; - static constexpr alignas(16) int32_t g_negateMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 }; - static constexpr alignas(16) int32_t g_negateXMask[4] = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 }; - static constexpr alignas(16) int32_t g_negateYMask[4] = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 }; - static constexpr alignas(16) int32_t g_negateZMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 }; - static constexpr alignas(16) int32_t g_negateWMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 }; - static constexpr alignas(16) int32_t g_negateXYZMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 }; - static constexpr alignas(16) int32_t g_wMask[4] = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 }; + alignas(16) static constexpr float g_vec1111[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + alignas(16) static constexpr float g_vec1000[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + alignas(16) static constexpr float g_vec0100[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + alignas(16) static constexpr float g_vec0010[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + alignas(16) static constexpr float g_vec0001[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + alignas(16) static constexpr float g_Pi[4] = { Constants::Pi, Constants::Pi, Constants::Pi, Constants::Pi }; + alignas(16) static constexpr float g_TwoPi[4] = { Constants::TwoPi, Constants::TwoPi, Constants::TwoPi, Constants::TwoPi }; + alignas(16) static constexpr float g_HalfPi[4] = { Constants::HalfPi, Constants::HalfPi, Constants::HalfPi, Constants::HalfPi }; + alignas(16) static constexpr float g_QuarterPi[4] = { Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi, Constants::QuarterPi }; + alignas(16) static constexpr float g_TwoOverPi[4] = { Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi, Constants::TwoOverPi }; + alignas(16) static constexpr int32_t g_absMask[4] = { (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff, (int32_t)0x7fffffff }; + alignas(16) static constexpr int32_t g_negateMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000 }; + alignas(16) static constexpr int32_t g_negateXMask[4] = { (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000 }; + alignas(16) static constexpr int32_t g_negateYMask[4] = { (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000, (int32_t)0x00000000 }; + alignas(16) static constexpr int32_t g_negateZMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000, (int32_t)0x00000000 }; + alignas(16) static constexpr int32_t g_negateWMask[4] = { (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x00000000, (int32_t)0x80000000 }; + alignas(16) static constexpr int32_t g_negateXYZMask[4] = { (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x80000000, (int32_t)0x00000000 }; + alignas(16) static constexpr int32_t g_wMask[4] = { (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0xffffffff, (int32_t)0x00000000 }; } } diff --git a/Code/Legacy/CryCommon/Cry_Camera.h b/Code/Legacy/CryCommon/Cry_Camera.h index 3d9d25e3bb..d80a3d120c 100644 --- a/Code/Legacy/CryCommon/Cry_Camera.h +++ b/Code/Legacy/CryCommon/Cry_Camera.h @@ -2146,7 +2146,7 @@ inline uint8 CCamera::IsOBBVisible_EH(const Vec3& wpos, const OBB& obb, f32 usca //--- ADDITIONAL-TEST --- //------------------------------------------------------------------------------ -extern alignas(64) uint32 BoxSides[]; +alignas(64) extern uint32 BoxSides[]; // Description: // A box can easily straddle one of the view-frustum planes far From 7d4f8e42812c352445a9ba971347fe8c620ce61b Mon Sep 17 00:00:00 2001 From: pereslav Date: Tue, 24 Aug 2021 13:39:54 +0100 Subject: [PATCH 22/27] Added a helper function for constructing CollisionGroup from CollisionGroups::Id. Removed remaining touch bending related code Signed-off-by: pereslav --- .../Physics/Collision/CollisionGroups.cpp | 7 +++ .../Physics/Collision/CollisionGroups.h | 6 ++- .../Physics/Collision/CollisionLayers.h | 1 - Gems/PhysX/Code/Include/PhysX/UserDataTypes.h | 53 ++++++------------- .../Code/Include/PhysX/UserDataTypes.inl | 27 +++------- 5 files changed, 34 insertions(+), 60 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp index 84e0184462..a0fcd2e206 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp @@ -309,5 +309,12 @@ namespace AzPhysics group.SetLayer(layer, true); return group; } + + CollisionGroup MakeCollisionGroup(const CollisionGroups::Id& id) + { + CollisionGroup group; + Physics::CollisionRequestBus::BroadcastResult(group, &Physics::CollisionRequests::GetCollisionGroupById, id); + return group; + } } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h index 5340a1a344..59f1cfb885 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h @@ -34,7 +34,6 @@ namespace AzPhysics static const CollisionGroup None; //!< Collide with nothing static const CollisionGroup All; //!< Collide with everything - static const CollisionGroup All_NoTouchBend; //!< Collide with everything, except Touch Bendable Vegetation. //! Construct a Group with the given bitmask. //! The each bit in the bitmask corresponds to a CollisionLayer. @@ -174,4 +173,9 @@ namespace AzPhysics private: AZStd::vector m_groups; }; + + //! Construct a Group with the given Id of a collision group. + //! This will lookup the group Id to retrieve the group mask. If not found, CollisionGroup::All is returned. + //! @param id The Id of the group to look up the group mask. + CollisionGroup MakeCollisionGroup(const CollisionGroups::Id& id); } diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h index 6b5a4cd2a9..01141c611c 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionLayers.h @@ -31,7 +31,6 @@ namespace AzPhysics static void Reflect(AZ::ReflectContext* context); static const CollisionLayer Default; //!< Default collision layer, 0. - static const CollisionLayer TouchBend; //!< Touch Bendable Vegetation collision layer. //! Construct a layer with the given index. //! @param index The index of the layer. Must be between 0 - CollisionLayers::MaxCollisionLayers. Default CollisionLayer::Default. diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h index 03add0a7ec..f41526fa08 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h @@ -22,49 +22,15 @@ namespace AzPhysics namespace PhysX { - enum class BaseActorType : AZ::u32 - { - PHYSX_DEFAULT = 0, - TOUCHBENDING_TRIGGER, - }; - ///PxActor.userData is the custom data pointer that NVIDIA PhysX provides for applications to attach - ///private data. The PhysX Gem requires that this userData points to objects that subclass BaseActorData. - ///For Example: - ///The TouchBending Gem defines "struct TouchBendingInstanceHandle : public PhysX::BaseActorData", - ///While regular PhysX Gem Components use "class ActorData : public BaseActorData". - class BaseActorData - { - protected: - using PxActorUniquePtr = AZStd::unique_ptr >; - - ///This is an arbitary value used to verify the cast from void* userdata pointer on a pxActor to BaseActorData - ///is safe. If m_sanity does not have this value, then it is not safe to use the casted pointer. - ///Helps to debug if someone is setting userData pointer to something other than this class during development - static const AZ::u32 s_sanityValue = 0xba5eba11; - - AZ::u32 m_sanity = s_sanityValue; - BaseActorType m_actorType = BaseActorType::PHYSX_DEFAULT; - PxActorUniquePtr m_actor; - - BaseActorData() = default; - BaseActorData(BaseActorType type, physx::PxActor* actor); - BaseActorData(BaseActorData&& other); - BaseActorData& operator=(BaseActorData&& other); - - public: - bool IsValid() const; - BaseActorType GetType() const; - }; - - - class ActorData : public BaseActorData + ///private data. The PhysX Gem requires that this userData points to ActorData objects. + class ActorData { public: ActorData() = default; ActorData(physx::PxActor* actor); - ActorData(ActorData&& actorData) = default; - ActorData& operator=(ActorData&& actorData) = default; + ActorData(ActorData&& actorData); + ActorData& operator=(ActorData&& actorData); void Invalidate(); AZ::EntityId GetEntityId() const; @@ -86,7 +52,18 @@ namespace PhysX AzPhysics::SimulatedBody* GetSimulatedBody() const; + bool IsValid() const; + private: + using PxActorUniquePtr = AZStd::unique_ptr >; + + ///This is an arbitary value used to verify the cast from void* userdata pointer on a pxActor to ActorData + ///is safe. If m_sanity does not have this value, then it is not safe to use the casted pointer. + ///Helps to debug if someone is setting userData pointer to something other than this class during development + static const AZ::u32 s_sanityValue = 0xba5eba11; + + AZ::u32 m_sanity = s_sanityValue; + PxActorUniquePtr m_actor; struct Payload { diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl index d0fa850dbf..97d0350a90 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl @@ -9,9 +9,8 @@ namespace PhysX { - // BaseActorData START **************************************************** - inline BaseActorData::BaseActorData(BaseActorType type, physx::PxActor* actor) : - m_sanity(s_sanityValue), m_actorType(type) + inline ActorData::ActorData(physx::PxActor* actor) + : m_sanity(s_sanityValue) { auto nullUserData = [](physx::PxActor* actorToSet) { @@ -23,38 +22,26 @@ namespace PhysX actor->userData = this; } - inline BaseActorData::BaseActorData(BaseActorData&& other) : - m_sanity(s_sanityValue), m_actorType(other.m_actorType), m_actor(AZStd::move(other.m_actor)) + inline ActorData::ActorData(ActorData&& other) + : m_sanity(s_sanityValue) + , m_actor(AZStd::move(other.m_actor)) { m_actor->userData = this; } - inline BaseActorData& BaseActorData::operator=(BaseActorData&& other) + inline ActorData& ActorData::operator=(ActorData&& other) { m_sanity = s_sanityValue; - m_actorType = other.m_actorType; m_actor = AZStd::move(other.m_actor); m_actor->userData = this; return *this; } - inline bool BaseActorData::IsValid() const + inline bool ActorData::IsValid() const { return m_sanity == s_sanityValue; } - inline BaseActorType BaseActorData::GetType() const - { - return m_actorType; - } - // BaseActorData END ****************************************************** - - - // ActorData START ******************************************************** - inline ActorData::ActorData(physx::PxActor* actor) : BaseActorData(BaseActorType::PHYSX_DEFAULT, actor) - { - } - inline void ActorData::Invalidate() { m_actor = nullptr; From 21605f15ccc934133022d0ed68037425fd1c1a15 Mon Sep 17 00:00:00 2001 From: pereslav Date: Tue, 24 Aug 2021 16:00:00 +0100 Subject: [PATCH 23/27] CR Feedback addressing Signed-off-by: pereslav --- .../AzFramework/Physics/Collision/CollisionGroups.cpp | 2 +- .../AzFramework/Physics/Collision/CollisionGroups.h | 4 ++-- Gems/PhysX/Code/Include/PhysX/UserDataTypes.h | 4 ++-- Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp index a0fcd2e206..2100b0c394 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.cpp @@ -310,7 +310,7 @@ namespace AzPhysics return group; } - CollisionGroup MakeCollisionGroup(const CollisionGroups::Id& id) + CollisionGroup GetCollisionGroupById(const CollisionGroups::Id& id) { CollisionGroup group; Physics::CollisionRequestBus::BroadcastResult(group, &Physics::CollisionRequests::GetCollisionGroupById, id); diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h index 59f1cfb885..8f75d2560d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Collision/CollisionGroups.h @@ -174,8 +174,8 @@ namespace AzPhysics AZStd::vector m_groups; }; - //! Construct a Group with the given Id of a collision group. + //! Retrieves a Group with the given Id of a collision group. //! This will lookup the group Id to retrieve the group mask. If not found, CollisionGroup::All is returned. //! @param id The Id of the group to look up the group mask. - CollisionGroup MakeCollisionGroup(const CollisionGroups::Id& id); + CollisionGroup GetCollisionGroupById(const CollisionGroups::Id& id); } diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h index f41526fa08..aad2a716ec 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.h @@ -60,9 +60,9 @@ namespace PhysX ///This is an arbitary value used to verify the cast from void* userdata pointer on a pxActor to ActorData ///is safe. If m_sanity does not have this value, then it is not safe to use the casted pointer. ///Helps to debug if someone is setting userData pointer to something other than this class during development - static const AZ::u32 s_sanityValue = 0xba5eba11; + static constexpr AZ::u32 SanityValue = 0xba5eba11; - AZ::u32 m_sanity = s_sanityValue; + AZ::u32 m_sanity = SanityValue; PxActorUniquePtr m_actor; struct Payload diff --git a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl index 97d0350a90..e01163d7ee 100644 --- a/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl +++ b/Gems/PhysX/Code/Include/PhysX/UserDataTypes.inl @@ -10,7 +10,6 @@ namespace PhysX { inline ActorData::ActorData(physx::PxActor* actor) - : m_sanity(s_sanityValue) { auto nullUserData = [](physx::PxActor* actorToSet) { @@ -23,23 +22,25 @@ namespace PhysX } inline ActorData::ActorData(ActorData&& other) - : m_sanity(s_sanityValue) + : m_sanity(other.m_sanity) , m_actor(AZStd::move(other.m_actor)) + , m_payload(AZStd::move(other.m_payload)) { m_actor->userData = this; } inline ActorData& ActorData::operator=(ActorData&& other) { - m_sanity = s_sanityValue; + m_sanity = other.m_sanity; m_actor = AZStd::move(other.m_actor); m_actor->userData = this; + m_payload = AZStd::move(other.m_payload); return *this; } inline bool ActorData::IsValid() const { - return m_sanity == s_sanityValue; + return m_sanity == SanityValue; } inline void ActorData::Invalidate() @@ -136,5 +137,4 @@ namespace PhysX return nullptr; } } - // ActorData END ******************************************************** } //namespace PhysX From ce85bb3b7d53ccbc6591e62f19c35339027e0dd0 Mon Sep 17 00:00:00 2001 From: Shirang Jia Date: Tue, 24 Aug 2021 10:43:17 -0700 Subject: [PATCH 24/27] Add awsi deployment as a non-blocking step in nightly pipeline (#3397) * Add awsi deployment as a non-blocking step in nightly pipeline * Make step fail if it's not a non-blocking step --- scripts/build/Jenkins/Jenkinsfile | 13 +++++++- .../build/Platform/Windows/build_config.json | 17 ++++++++-- scripts/build/Platform/Windows/pipeline.json | 32 ++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/scripts/build/Jenkins/Jenkinsfile b/scripts/build/Jenkins/Jenkinsfile index 6231f9006d..b2c06bc720 100644 --- a/scripts/build/Jenkins/Jenkinsfile +++ b/scripts/build/Jenkins/Jenkinsfile @@ -473,7 +473,18 @@ def CreateSingleNode(Map pipelineConfig, def platform, def build_job, Map envVar if(build_job.value.steps) { //this is a pipe with many steps so create all the build stages build_job.value.steps.each { build_step -> build_job_name = build_step - CreateBuildStage(pipelineConfig, platform.key, build_step, envVars).call() + envVars = GetBuildEnvVars(platform.value.PIPELINE_ENV ?: EMPTY_JSON, platform.value.build_types[build_step].PIPELINE_ENV ?: EMPTY_JSON, pipelineName) + try { + CreateBuildStage(pipelineConfig, platform.key, build_step, envVars).call() + } + catch (Exception e) { + if (envVars['NONBLOCKING_STEP']?.toBoolean()) { + unstable(message: "Build step ${build_step} failed but it's a non-blocking step in build job ${build_job.key}") + } + else { + error "FAILURE: ${e}" + } + } } } else { CreateBuildStage(pipelineConfig, platform.key, build_job.key, envVars).call() diff --git a/scripts/build/Platform/Windows/build_config.json b/scripts/build/Platform/Windows/build_config.json index 8928794a43..583a73b58b 100644 --- a/scripts/build/Platform/Windows/build_config.json +++ b/scripts/build/Platform/Windows/build_config.json @@ -213,10 +213,18 @@ "ASSET_PROCESSOR_PLATFORMS": "pc,server" } }, - "periodic_test_profile_vs2019": { + "periodic_test_profile_vs2019_pipe": { "TAGS": [ "nightly-incremental", - "nightly-clean", + "nightly-clean" + ], + "steps": [ + "awsi_deployment", + "periodic_test_profile_vs2019" + ] + }, + "periodic_test_profile_vs2019": { + "TAGS": [ "weekly-build-metrics" ], "COMMAND": "build_test_windows.cmd", @@ -378,7 +386,10 @@ ] }, "awsi_deployment": { - "TAGS": ["awsi-deployment"], + "TAGS": [], + "PIPELINE_ENV": { + "NONBLOCKING_STEP": "True" + }, "COMMAND": "deploy_cdk_applications.cmd", "PARAMETERS": {} } diff --git a/scripts/build/Platform/Windows/pipeline.json b/scripts/build/Platform/Windows/pipeline.json index 4c736d2292..6be55ec82d 100644 --- a/scripts/build/Platform/Windows/pipeline.json +++ b/scripts/build/Platform/Windows/pipeline.json @@ -18,7 +18,37 @@ } }, "PIPELINE_JENKINS_PARAMETERS": { - "awsi-deployment": [ + "nightly-incremental": [ + { + "parameter_name": "O3DE_AWS_PROJECT_NAME", + "parameter_type": "string", + "default_value": "", + "use_last_run_value": true, + "description": "The name of the O3DE project that stacks should be deployed for." + }, + { + "parameter_name": "O3DE_AWS_DEPLOY_REGION", + "parameter_type": "string", + "default_value": "", + "use_last_run_value": true, + "description": "The region to deploy the stacks into." + }, + { + "parameter_name": "ASSUME_ROLE_ARN", + "parameter_type": "string", + "default_value": "", + "use_last_run_value": true, + "description": "The ARN of the IAM role to assume to retrieve temporary AWS credentials." + }, + { + "parameter_name": "COMMIT_ID", + "parameter_type": "string", + "default_value": "", + "use_last_run_value": true, + "description": "The commit ID for locking the version of CDK applications to deploy." + } + ], + "nightly-clean": [ { "parameter_name": "O3DE_AWS_PROJECT_NAME", "parameter_type": "string", From 40f41689ee6d6ffa7c5f0131cd7078181d6d5943 Mon Sep 17 00:00:00 2001 From: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> Date: Tue, 24 Aug 2021 13:29:50 -0500 Subject: [PATCH 25/27] Initial Terrain System (#3401) This represents the very beginnings of the Terrain System presented in Sig-Content RFC 4 ( https://github.com/o3de/sig-content/blob/main/rfcs/rfc-4-terrain-system.md ). There is some basic working functionality in this PR, but the system as a whole should not be considered working yet. The gem is disabled by default in all projects. All of the code below is contained in the Terrain Gem, which is disabled by default. The following components exist and can be experimented with, but should not be expected to be functionally complete yet: Terrain World - level component for enabling terrain Terrain World Debugger - level component for enabling terrain debugging features Terrain Layer Spawner - component for defining a region of terrain Terrain Height Gradient List - component for defining a list of gradients to use as terrain heights Signed-off-by: Mike Balfour <82224783+mbalfour-amzn@users.noreply.github.com> --- .../Assets/Shaders/Terrain/Terrain.azsl | 125 +++++ .../Assets/Shaders/Terrain/Terrain.shader | 37 ++ .../TerrainHeightGradientListComponent.cpp | 231 +++++++++ .../TerrainHeightGradientListComponent.h | 101 ++++ .../TerrainLayerSpawnerComponent.cpp | 160 ++++++ .../Components/TerrainLayerSpawnerComponent.h | 97 ++++ .../Components/TerrainSystemComponent.cpp | 13 + .../Components/TerrainWorldComponent.cpp | 123 +++++ .../Source/Components/TerrainWorldComponent.h | 64 +++ .../TerrainWorldDebuggerComponent.cpp | 322 ++++++++++++ .../TerrainWorldDebuggerComponent.h | 114 ++++ ...itorTerrainHeightGradientListComponent.cpp | 22 + ...EditorTerrainHeightGradientListComponent.h | 32 ++ .../EditorTerrainLayerSpawnerComponent.cpp | 22 + .../EditorTerrainLayerSpawnerComponent.h | 32 ++ .../EditorTerrainWorldComponent.cpp | 56 ++ .../EditorTerrainWorldComponent.h | 38 ++ .../EditorTerrainWorldDebuggerComponent.cpp | 56 ++ .../EditorTerrainWorldDebuggerComponent.h | 38 ++ .../Code/Source/EditorTerrainModule.cpp | 9 + Gems/Terrain/Code/Source/TerrainModule.cpp | 8 + .../TerrainFeatureProcessor.cpp | 490 ++++++++++++++++++ .../TerrainRenderer/TerrainFeatureProcessor.h | 145 ++++++ .../Source/TerrainSystem/TerrainSystem.cpp | 489 +++++++++++++++++ .../Code/Source/TerrainSystem/TerrainSystem.h | 120 +++++ .../Source/TerrainSystem/TerrainSystemBus.h | 120 +++++ .../Code/terrain_editor_shared_files.cmake | 8 + Gems/Terrain/Code/terrain_files.cmake | 13 + 28 files changed, 3085 insertions(+) create mode 100644 Gems/Terrain/Assets/Shaders/Terrain/Terrain.azsl create mode 100644 Gems/Terrain/Assets/Shaders/Terrain/Terrain.shader create mode 100644 Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp create mode 100644 Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.h create mode 100644 Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.cpp create mode 100644 Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.h create mode 100644 Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp create mode 100644 Gems/Terrain/Code/Source/Components/TerrainWorldComponent.h create mode 100644 Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp create mode 100644 Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.cpp create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.h create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.cpp create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.h create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp create mode 100644 Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.h create mode 100644 Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp create mode 100644 Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h create mode 100644 Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp create mode 100644 Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h create mode 100644 Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h diff --git a/Gems/Terrain/Assets/Shaders/Terrain/Terrain.azsl b/Gems/Terrain/Assets/Shaders/Terrain/Terrain.azsl new file mode 100644 index 0000000000..57d0909ae4 --- /dev/null +++ b/Gems/Terrain/Assets/Shaders/Terrain/Terrain.azsl @@ -0,0 +1,125 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + + +struct VertexInput +{ + float2 Position : POSITION; + float2 UV : UV; +}; + +struct VertexOutput +{ + float4 Position : SV_Position; + float3 Normal : NORMAL; + float2 UV : UV; +}; + +ShaderResourceGroup ObjectSrg : SRG_PerObject +{ + Texture2D HeightmapImage; + + Sampler LinearSampler + { + MinFilter = Linear; + MagFilter = Linear; + MipFilter = Linear; + AddressU = Clamp; + AddressV = Clamp; + AddressW = Clamp; + }; + + row_major float3x4 m_modelToWorld; + float m_heightScale; + float2 m_uvMin; + float2 m_uvMax; + float2 m_uvStep; +} + +float4x4 GetObject_WorldMatrix() +{ + float4x4 modelToWorld = float4x4( + float4(1, 0, 0, 0), + float4(0, 1, 0, 0), + float4(0, 0, 1, 0), + float4(0, 0, 0, 1)); + + modelToWorld[0] = ObjectSrg::m_modelToWorld[0]; + modelToWorld[1] = ObjectSrg::m_modelToWorld[1]; + modelToWorld[2] = ObjectSrg::m_modelToWorld[2]; + return modelToWorld; +} + +float GetHeight(float2 origUv) +{ + float2 uv = clamp(origUv, 0.0f, 1.0f); + return ObjectSrg::m_heightScale * (ObjectSrg::HeightmapImage.SampleLevel(ObjectSrg::LinearSampler, uv, 0).r - 0.5f); +} + +VertexOutput MainVS(in VertexInput input) +{ + VertexOutput output; + + // Clamp the UVs *after* lerping to ensure that everything aligns properly right to the edge. + // We use out-of-bounds UV values to denote vertices that need to be removed. + float2 origUv = lerp(ObjectSrg::m_uvMin, ObjectSrg::m_uvMax, input.UV); + float2 uv = clamp(origUv, 0.0f, 1.0f); + + // Loop up the height and calculate our final position. + float height = GetHeight(uv); + float3 worldPosition = mul(GetObject_WorldMatrix(), float4(input.Position, height, 1.0f)).xyz; + output.Position = mul(ViewSrg::m_viewProjectionMatrix, float4(worldPosition, 1.0f)); + + // Remove all vertices outside our bounds by turning them into NaN positions. + output.Position = output.Position / ((origUv.x >= 0.0f && origUv.x < 1.0f && origUv.y >= 0.0f && origUv.y < 1.0f) ? 1.0f : 0.0f); + + // Calculate normal + float2 gridSize = {1.0f, 1.0f}; + float up = GetHeight(uv + ObjectSrg::m_uvStep * float2(-1.0f, 0.0f)); + float right = GetHeight(uv + ObjectSrg::m_uvStep * float2( 0.0f, 1.0f)); + float down = GetHeight(uv + ObjectSrg::m_uvStep * float2( 1.0f, 0.0f)); + float left = GetHeight(uv + ObjectSrg::m_uvStep * float2( 0.0f, -1.0f)); + + float dydx = (right - left) * gridSize[0]; + float dydz = (down - up) * gridSize[1]; + + output.Normal = normalize(float3(dydx, 2.0f, dydz)); + + output.UV = uv; + return output; +} + +struct PixelOutput +{ + float4 m_color : SV_Target0; +}; + +PixelOutput MainPS(in VertexOutput input) +{ + PixelOutput output; + + // Hard-coded fake light direction + float3 lightDirection = normalize(float3(1.0, -1.0, 1.0)); + + // Fake light intensity ranges from 1.0 for normals directly facing the light to zero for those + // directly facing away. + float lightDot = dot(normalize(input.Normal), lightDirection); + float lightIntensity = lightDot * 0.5 + 0.5; + + // add a small amount of ambient and reduce direct light to keep in 0-1 range + lightIntensity = saturate(0.1 + lightIntensity * 0.9); + + // The lightIntensity should not affect alpha so only apply it to rgb. + //output.m_color.rgb = ((input.Normal + float3(1.0, 1.0, 1.0)) / 2.0); + output.m_color.rgb = float3(1.0, 1.0, 1.0) * lightIntensity; + output.m_color.a = 1.0f; + + return output; +} diff --git a/Gems/Terrain/Assets/Shaders/Terrain/Terrain.shader b/Gems/Terrain/Assets/Shaders/Terrain/Terrain.shader new file mode 100644 index 0000000000..f20f4201ae --- /dev/null +++ b/Gems/Terrain/Assets/Shaders/Terrain/Terrain.shader @@ -0,0 +1,37 @@ +{ + + "Source" : "Terrain", + + + "RasterState" : { "CullMode" : "None" }, + + "DepthStencilState" : { + "Depth" : { "Enable" : true, "CompareFunc" : "GreaterEqual" } + }, + + "BlendState" : { + "Enable" : true, + "BlendSource" : "One", + "BlendAlphaSource" : "One", + "BlendDest" : "AlphaSourceInverse", + "BlendAlphaDest" : "AlphaSourceInverse", + "BlendAlphaOp" : "Add" + }, + + "DrawList" : "forward", + + "ProgramSettings": + { + "EntryPoints": + [ + { + "name": "MainVS", + "type": "Vertex" + }, + { + "name": "MainPS", + "type": "Fragment" + } + ] + } +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp new file mode 100644 index 0000000000..d64f660d90 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.cpp @@ -0,0 +1,231 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace Terrain +{ + void TerrainHeightGradientListConfig::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("GradientEntities", &TerrainHeightGradientListConfig::m_gradientEntities) + ; + + AZ::EditContext* edit = serialize->GetEditContext(); + if (edit) + { + edit->Class( + "Terrain Height Gradient List Component", "Provide height data for a region of the world") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + + ->DataElement(0, &TerrainHeightGradientListConfig::m_gradientEntities, "Gradient Entities", "Ordered list of gradients to use as height providers.") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true) + ->Attribute(AZ::Edit::Attributes::RequiredService, AZ_CRC_CE("GradientService")) + ; + } + } + } + + void TerrainHeightGradientListComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainHeightProviderService")); + } + + void TerrainHeightGradientListComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainHeightProviderService")); + services.push_back(AZ_CRC_CE("GradientService")); + } + + void TerrainHeightGradientListComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainAreaService")); + services.push_back(AZ_CRC_CE("BoxShapeService")); + } + + void TerrainHeightGradientListComponent::Reflect(AZ::ReflectContext* context) + { + TerrainHeightGradientListConfig::Reflect(context); + + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(0) + ->Field("Configuration", &TerrainHeightGradientListComponent::m_configuration) + ; + } + } + + TerrainHeightGradientListComponent::TerrainHeightGradientListComponent(const TerrainHeightGradientListConfig& configuration) + : m_configuration(configuration) + { + } + + void TerrainHeightGradientListComponent::Activate() + { + LmbrCentral::DependencyNotificationBus::Handler::BusConnect(GetEntityId()); + Terrain::TerrainAreaHeightRequestBus::Handler::BusConnect(GetEntityId()); + AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect(); + + // Make sure we get update notifications whenever this entity or any dependent gradient entity changes in any way. + // We'll use that to notify the terrain system that the height information needs to be refreshed. + m_dependencyMonitor.Reset(); + m_dependencyMonitor.ConnectOwner(GetEntityId()); + m_dependencyMonitor.ConnectDependency(GetEntityId()); + + for (auto& entityId : m_configuration.m_gradientEntities) + { + if (entityId != GetEntityId()) + { + m_dependencyMonitor.ConnectDependency(entityId); + } + } + + // Cache any height data needed and notify that the area has changed. + OnCompositionChanged(); + } + + void TerrainHeightGradientListComponent::Deactivate() + { + m_dependencyMonitor.Reset(); + AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect(); + Terrain::TerrainAreaHeightRequestBus::Handler::BusDisconnect(); + LmbrCentral::DependencyNotificationBus::Handler::BusDisconnect(); + + // Since this height data will no longer exist, notify the terrain system to refresh the area. + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RefreshArea, GetEntityId()); + } + + bool TerrainHeightGradientListComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) + { + if (auto config = azrtti_cast(baseConfig)) + { + m_configuration = *config; + return true; + } + return false; + } + + bool TerrainHeightGradientListComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const + { + if (auto config = azrtti_cast(outBaseConfig)) + { + *config = m_configuration; + return true; + } + return false; + } + + float TerrainHeightGradientListComponent::GetHeight(float x, float y) + { + float maxSample = 0.0f; + + GradientSignal::GradientSampleParams params(AZ::Vector3(x, y, 0.0f)); + + // Right now, when the list contains multiple entries, we will use the highest point from each gradient. + // This is needed in part because gradients don't really have world bounds, so they exist everywhere but generally have a value + // of 0 outside their data bounds if they're using bounded data. We should examine the possibility of extending the gradient API + // to provide actual bounds so that it's possible to detect if the gradient even 'exists' in an area, at which point we could just + // make this list a prioritized list from top to bottom for any points that overlap. + for (auto& gradientId : m_configuration.m_gradientEntities) + { + float sample = 0.0f; + GradientSignal::GradientRequestBus::EventResult(sample, gradientId, &GradientSignal::GradientRequestBus::Events::GetValue, params); + maxSample = AZ::GetMax(maxSample, sample); + } + + const float height = AZ::Lerp(m_cachedShapeBounds.GetMin().GetZ(), m_cachedShapeBounds.GetMax().GetZ(), maxSample); + + return AZ::GetClamp(height, m_cachedMinWorldHeight, m_cachedMaxWorldHeight); + } + + void TerrainHeightGradientListComponent::GetHeight( + const AZ::Vector3& inPosition, AZ::Vector3& outPosition, [[maybe_unused]] Sampler sampleFilter = Sampler::DEFAULT) + { + const float height = GetHeight(inPosition.GetX(), inPosition.GetY()); + outPosition.SetZ(height); + } + + void TerrainHeightGradientListComponent::GetNormal( + const AZ::Vector3& inPosition, AZ::Vector3& outNormal, [[maybe_unused]] Sampler sampleFilter = Sampler::DEFAULT) + { + const float x = inPosition.GetX(); + const float y = inPosition.GetY(); + + if ((x >= m_cachedShapeBounds.GetMin().GetX()) && (x <= m_cachedShapeBounds.GetMax().GetX()) && + (y >= m_cachedShapeBounds.GetMin().GetY()) && (y <= m_cachedShapeBounds.GetMax().GetY())) + { + AZ::Vector2 fRange = (m_cachedHeightQueryResolution / 2.0f) + AZ::Vector2(0.05f); + + AZ::Vector3 v1(x - fRange.GetX(), y - fRange.GetY(), GetHeight(x - fRange.GetX(), y - fRange.GetY())); + AZ::Vector3 v2(x - fRange.GetX(), y + fRange.GetY(), GetHeight(x - fRange.GetX(), y + fRange.GetY())); + AZ::Vector3 v3(x + fRange.GetX(), y - fRange.GetY(), GetHeight(x + fRange.GetX(), y - fRange.GetY())); + AZ::Vector3 v4(x + fRange.GetX(), y + fRange.GetY(), GetHeight(x + fRange.GetX(), y + fRange.GetY())); + outNormal = (v3 - v2).Cross(v4 - v1).GetNormalized(); + } + } + + + void TerrainHeightGradientListComponent::OnCompositionChanged() + { + RefreshMinMaxHeights(); + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RefreshArea, GetEntityId()); + } + + void TerrainHeightGradientListComponent::RefreshMinMaxHeights() + { + // Get the height range of our height provider based on the shape component. + LmbrCentral::ShapeComponentRequestsBus::EventResult(m_cachedShapeBounds, GetEntityId(), &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb); + + // Get the height range of the entire world + m_cachedHeightQueryResolution = AZ::Vector2(1.0f); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + m_cachedHeightQueryResolution, &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainGridResolution); + + AZ::Aabb worldBounds = AZ::Aabb::CreateNull(); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + worldBounds, &AzFramework::Terrain::TerrainDataRequestBus::Events::GetTerrainAabb); + + // Save off the min/max heights so that we don't have to re-query them on every single height query. + m_cachedMinWorldHeight = worldBounds.GetMin().GetZ(); + m_cachedMaxWorldHeight = worldBounds.GetMax().GetZ(); + } + + void TerrainHeightGradientListComponent::OnTerrainDataChanged( + [[maybe_unused]] const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) + { + if (dataChangedMask & TerrainDataChangedMask::Settings) + { + // If the terrain system settings changed, it's possible that the world bounds have changed, which can affect our height data. + // Refresh the min/max heights and notify that the height data for this area needs to be refreshed. + OnCompositionChanged(); + } + } + +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.h b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.h new file mode 100644 index 0000000000..7635680815 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainHeightGradientListComponent.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + + +namespace LmbrCentral +{ + template + class EditorWrappedComponentBase; +} + +namespace Terrain +{ + class TerrainHeightGradientListConfig + : public AZ::ComponentConfig + { + public: + AZ_CLASS_ALLOCATOR(TerrainHeightGradientListConfig, AZ::SystemAllocator, 0); + AZ_RTTI(TerrainHeightGradientListConfig, "{C5FD71A9-0722-4D4C-B605-EBEBF90C628F}", AZ::ComponentConfig); + static void Reflect(AZ::ReflectContext* context); + + AZStd::vector m_gradientEntities; + }; + + + class TerrainHeightGradientListComponent + : public AZ::Component + , private Terrain::TerrainAreaHeightRequestBus::Handler + , private LmbrCentral::DependencyNotificationBus::Handler + , private AzFramework::Terrain::TerrainDataNotificationBus::Handler + { + public: + template + friend class LmbrCentral::EditorWrappedComponentBase; + AZ_COMPONENT(TerrainHeightGradientListComponent, "{1BB3BA6C-6D4A-4636-B542-F23ECBA8F2AB}"); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void Reflect(AZ::ReflectContext* context); + + TerrainHeightGradientListComponent(const TerrainHeightGradientListConfig& configuration); + TerrainHeightGradientListComponent() = default; + ~TerrainHeightGradientListComponent() = default; + + void GetHeight(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, Sampler sampleFilter) override; + void GetNormal(const AZ::Vector3& inPosition, AZ::Vector3& outNormal, Sampler sampleFilter) override; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override; + bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override; + + ////////////////////////////////////////////////////////////////////////// + // LmbrCentral::DependencyNotificationBus + void OnCompositionChanged() override; + + ////////////////////////////////////////////////////////////////////////// + // AzFramework::Terrain::TerrainDataNotificationBus + void OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) override; + + private: + TerrainHeightGradientListConfig m_configuration; + + /////////////////////////////////////////// + void GetNormalSynchronous(float x, float y, AZ::Vector3& normal); + + void RefreshMinMaxHeights(); + float GetHeight(float x, float y); + + float m_cachedMinWorldHeight{ 0.0f }; + float m_cachedMaxWorldHeight{ 0.0f }; + AZ::Vector2 m_cachedHeightQueryResolution{ 1.0f, 1.0f }; + AZ::Aabb m_cachedShapeBounds; + + LmbrCentral::DependencyMonitor m_dependencyMonitor; + }; +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.cpp new file mode 100644 index 0000000000..06372a3490 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace Terrain +{ + void TerrainLayerSpawnerConfig::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("Layer", &TerrainLayerSpawnerConfig::m_layer) + ->Field("Priority", &TerrainLayerSpawnerConfig::m_priority) + ->Field("UseGroundPlane", &TerrainLayerSpawnerConfig::m_useGroundPlane) + ; + + AZ::EditContext* edit = serialize->GetEditContext(); + if (edit) + { + edit->Class( + "Terrain Layer Spawner Component", "Provide terrain data for a region of the world") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + + ->DataElement(AZ::Edit::UIHandlers::ComboBox, &TerrainLayerSpawnerConfig::m_layer, "Layer Priority", "Defines a high level order that terrain spawners are applied") + ->Attribute(AZ::Edit::Attributes::EnumValues, &TerrainLayerSpawnerConfig::GetSelectableLayers) + ->DataElement(AZ::Edit::UIHandlers::Slider, &TerrainLayerSpawnerConfig::m_priority, "Sub Priority", "Defines order terrain spawners are applied within a layer. Larger numbers = higher priority") + ->Attribute(AZ::Edit::Attributes::Min, AreaConstants::s_priorityMin) + ->Attribute(AZ::Edit::Attributes::Max, AreaConstants::s_priorityMax) + ->Attribute(AZ::Edit::Attributes::SoftMin, AreaConstants::s_priorityMin) + ->Attribute(AZ::Edit::Attributes::SoftMax, AreaConstants::s_prioritySoftMax) + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainLayerSpawnerConfig::m_useGroundPlane, "Use Ground Plane", "Determines whether or not to provide a default ground plane") + ; + } + } + } + + AZStd::vector> TerrainLayerSpawnerConfig::GetSelectableLayers() const + { + AZStd::vector> selectableLayers; + selectableLayers.push_back({ AreaConstants::s_backgroundLayer, AZStd::string("Background") }); + selectableLayers.push_back({ AreaConstants::s_foregroundLayer, AZStd::string("Foreground") }); + return selectableLayers; + } + + + void TerrainLayerSpawnerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC("TerrainAreaService")); + } + + void TerrainLayerSpawnerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC("TerrainAreaService")); + } + + void TerrainLayerSpawnerComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC("BoxShapeService")); + } + + void TerrainLayerSpawnerComponent::Reflect(AZ::ReflectContext* context) + { + TerrainLayerSpawnerConfig::Reflect(context); + + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(0) + ->Field("Configuration", &TerrainLayerSpawnerComponent::m_configuration) + ; + } + } + + TerrainLayerSpawnerComponent::TerrainLayerSpawnerComponent(const TerrainLayerSpawnerConfig& configuration) + : m_configuration(configuration) + { + } + + void TerrainLayerSpawnerComponent::Activate() + { + AZ::TransformNotificationBus::Handler::BusConnect(GetEntityId()); + LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(GetEntityId()); + TerrainAreaRequestBus::Handler::BusConnect(GetEntityId()); + + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RegisterArea, GetEntityId()); + } + + void TerrainLayerSpawnerComponent::Deactivate() + { + TerrainAreaRequestBus::Handler::BusDisconnect(); + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::UnregisterArea, GetEntityId()); + + AZ::TransformNotificationBus::Handler::BusDisconnect(); + LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect(); + } + + bool TerrainLayerSpawnerComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) + { + if (auto config = azrtti_cast(baseConfig)) + { + m_configuration = *config; + return true; + } + return false; + } + + bool TerrainLayerSpawnerComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const + { + if (auto config = azrtti_cast(outBaseConfig)) + { + *config = m_configuration; + return true; + } + return false; + } + + void TerrainLayerSpawnerComponent::OnTransformChanged([[maybe_unused]] const AZ::Transform& local, [[maybe_unused]] const AZ::Transform& world) + { + RefreshArea(); + } + + void TerrainLayerSpawnerComponent::OnShapeChanged([[maybe_unused]] ShapeChangeReasons changeReason) + { + RefreshArea(); + } + + void TerrainLayerSpawnerComponent::RegisterArea() + { + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RegisterArea, GetEntityId()); + } + + void TerrainLayerSpawnerComponent::RefreshArea() + { + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::RefreshArea, GetEntityId()); + } +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.h b/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.h new file mode 100644 index 0000000000..1f1ae90227 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainLayerSpawnerComponent.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include + +namespace LmbrCentral +{ + template + class EditorWrappedComponentBase; +} + +namespace Terrain +{ + namespace AreaConstants + { + static const AZ::u32 s_backgroundLayer = 0; + static const AZ::u32 s_foregroundLayer = 1; + static const AZ::u32 s_priorityMin = 0; + static const AZ::u32 s_priorityMax = 10000; //arbitrary number because std::numeric_limits::max() always dislays -1 in RPE + static const AZ::u32 s_prioritySoftMax = 100; //design specified slider range + } + + class TerrainLayerSpawnerConfig + : public AZ::ComponentConfig + { + public: + AZ_CLASS_ALLOCATOR(TerrainLayerSpawnerConfig, AZ::SystemAllocator, 0); + AZ_RTTI(TerrainLayerSpawnerConfig, "{8E0695DE-E843-4858-BAEA-70953E74C810}", AZ::ComponentConfig); + static void Reflect(AZ::ReflectContext* context); + + AZStd::vector> GetSelectableLayers() const; + AZ::u32 m_layer = AreaConstants::s_foregroundLayer; + AZ::u32 m_priority = AreaConstants::s_priorityMin; + bool m_useGroundPlane = true; + }; + + + class TerrainLayerSpawnerComponent + : public AZ::Component + , private AZ::TransformNotificationBus::Handler + , private LmbrCentral::ShapeComponentNotificationsBus::Handler + , private Terrain::TerrainAreaRequestBus::Handler + { + public: + template + friend class LmbrCentral::EditorWrappedComponentBase; + AZ_COMPONENT(TerrainLayerSpawnerComponent, "{3848605F-A4EA-478C-B710-84AB8DCA9EC5}"); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void Reflect(AZ::ReflectContext* context); + + TerrainLayerSpawnerComponent(const TerrainLayerSpawnerConfig& configuration); + TerrainLayerSpawnerComponent() = default; + ~TerrainLayerSpawnerComponent() = default; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override; + bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override; + + + ////////////////////////////////////////////////////////////////////////// + // AZ::TransformNotificationBus::Handler + void OnTransformChanged(const AZ::Transform& local, const AZ::Transform& world) override; + + // ShapeComponentNotificationsBus + void OnShapeChanged(ShapeChangeReasons changeReason) override; + + void RegisterArea() override; + void RefreshArea() override; + + private: + TerrainLayerSpawnerConfig m_configuration; + }; +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainSystemComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainSystemComponent.cpp index dea7babbbc..afaf0470b4 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainSystemComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainSystemComponent.cpp @@ -14,6 +14,8 @@ #include #include +#include +#include namespace Terrain { @@ -32,6 +34,8 @@ namespace Terrain ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ; } + + Terrain::TerrainFeatureProcessor::Reflect(context); } } @@ -60,9 +64,18 @@ namespace Terrain void TerrainSystemComponent::Activate() { + // Currently, the Terrain System Component owns the Terrain System instance because the Terrain World component gets recreated + // every time an entity is added or removed to a level. If this ever changes, the Terrain System ownership could move into + // the level component. + m_terrainSystem = new TerrainSystem(); + AZ::RPI::FeatureProcessorFactory::Get()->RegisterFeatureProcessor(); } void TerrainSystemComponent::Deactivate() { + delete m_terrainSystem; + m_terrainSystem = nullptr; + + AZ::RPI::FeatureProcessorFactory::Get()->UnregisterFeatureProcessor(); } } diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp new file mode 100644 index 0000000000..e2af58e3eb --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace Terrain +{ + void TerrainWorldConfig::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("WorldMin", &TerrainWorldConfig::m_worldMin) + ->Field("WorldMax", &TerrainWorldConfig::m_worldMax) + ->Field("HeightQueryResolution", &TerrainWorldConfig::m_heightQueryResolution) + ; + + AZ::EditContext* edit = serialize->GetEditContext(); + if (edit) + { + edit->Class( + "Terrain World Component", "Data required for the terrain system to run") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector({ AZ_CRC_CE("Level") })) + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_worldMin, "World Bounds (Min)", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_worldMax, "World Bounds (Max)", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldConfig::m_heightQueryResolution, "Height Query Resolution (m)", "") + ; + } + } + } + + void TerrainWorldComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainService")); + } + + void TerrainWorldComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainService")); + } + + void TerrainWorldComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& services) + { + } + + void TerrainWorldComponent::Reflect(AZ::ReflectContext* context) + { + TerrainWorldConfig::Reflect(context); + + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(0) + ->Field("Configuration", &TerrainWorldComponent::m_configuration) + ; + } + } + + TerrainWorldComponent::TerrainWorldComponent(const TerrainWorldConfig& configuration) + : m_configuration(configuration) + { + } + + TerrainWorldComponent::~TerrainWorldComponent() + { + } + + void TerrainWorldComponent::Activate() + { + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::SetWorldMin, m_configuration.m_worldMin); + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::SetWorldMax, m_configuration.m_worldMax); + TerrainSystemServiceRequestBus::Broadcast( + &TerrainSystemServiceRequestBus::Events::SetHeightQueryResolution, m_configuration.m_heightQueryResolution); + + // Currently, the Terrain System Component owns the Terrain System instance because the Terrain World component gets recreated + // every time an entity is added or removed to a level. If this ever changes, the Terrain System ownership could move into + // the level component. + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Activate); + } + + void TerrainWorldComponent::Deactivate() + { + TerrainSystemServiceRequestBus::Broadcast(&TerrainSystemServiceRequestBus::Events::Deactivate); + } + + bool TerrainWorldComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) + { + if (auto config = azrtti_cast(baseConfig)) + { + m_configuration = *config; + return true; + } + return false; + } + + bool TerrainWorldComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const + { + if (auto config = azrtti_cast(outBaseConfig)) + { + *config = m_configuration; + return true; + } + return false; + } +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.h b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.h new file mode 100644 index 0000000000..2dfe1135c8 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldComponent.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +namespace LmbrCentral +{ + template + class EditorWrappedComponentBase; +} + +namespace Terrain +{ + class TerrainWorldConfig + : public AZ::ComponentConfig + { + public: + AZ_CLASS_ALLOCATOR(TerrainWorldConfig, AZ::SystemAllocator, 0); + AZ_RTTI(TerrainWorldConfig, "{295844DB-20DD-45B2-94DB-4245D5AE9AFF}", AZ::ComponentConfig); + static void Reflect(AZ::ReflectContext* context); + + AZ::Vector3 m_worldMin{ 0.0f, 0.0f, 0.0f }; + AZ::Vector3 m_worldMax{ 1024.0f, 1024.0f, 1024.0f }; + AZ::Vector2 m_heightQueryResolution{ 1.0f, 1.0f }; + }; + + + class TerrainWorldComponent + : public AZ::Component + { + public: + template + friend class LmbrCentral::EditorWrappedComponentBase; + AZ_COMPONENT(TerrainWorldComponent, "{4734EFDC-135D-4BF5-BE57-4F9AD03ADF78}"); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void Reflect(AZ::ReflectContext* context); + + TerrainWorldComponent(const TerrainWorldConfig& configuration); + TerrainWorldComponent() = default; + ~TerrainWorldComponent() override; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override; + bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override; + + private: + TerrainWorldConfig m_configuration; + }; +} diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp new file mode 100644 index 0000000000..1fea51ded4 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.cpp @@ -0,0 +1,322 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +namespace Terrain +{ + void TerrainWorldDebuggerConfig::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(1) + ->Field("DebugWireframe", &TerrainWorldDebuggerConfig::m_drawWireframe) + ->Field("DebugWorldBounds", &TerrainWorldDebuggerConfig::m_drawWorldBounds) + ; + + AZ::EditContext* edit = serialize->GetEditContext(); + if (edit) + { + edit->Class( + "Terrain World Debugger Component", "Optional component for enabling terrain debugging features.") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector({ AZ_CRC_CE("Level") })) + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldDebuggerConfig::m_drawWireframe, "Show Wireframe", "") + ->DataElement(AZ::Edit::UIHandlers::Default, &TerrainWorldDebuggerConfig::m_drawWorldBounds, "Show World Bounds", ""); + } + } + } + + void TerrainWorldDebuggerComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainDebugService")); + } + + void TerrainWorldDebuggerComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainDebugService")); + } + + void TerrainWorldDebuggerComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services) + { + services.push_back(AZ_CRC_CE("TerrainService")); + } + + void TerrainWorldDebuggerComponent::Reflect(AZ::ReflectContext* context) + { + TerrainWorldDebuggerConfig::Reflect(context); + + AZ::SerializeContext* serialize = azrtti_cast(context); + if (serialize) + { + serialize->Class() + ->Version(0) + ->Field("Configuration", &TerrainWorldDebuggerComponent::m_configuration) + ; + } + } + + TerrainWorldDebuggerComponent::TerrainWorldDebuggerComponent(const TerrainWorldDebuggerConfig& configuration) + : m_configuration(configuration) + { + } + + TerrainWorldDebuggerComponent::~TerrainWorldDebuggerComponent() + { + } + + void TerrainWorldDebuggerComponent::Activate() + { + m_wireframeBounds = AZ::Aabb::CreateNull(); + + TerrainSystemServiceRequestBus::Broadcast( + &TerrainSystemServiceRequestBus::Events::SetDebugWireframe, m_configuration.m_drawWireframe); + + AzFramework::EntityDebugDisplayEventBus::Handler::BusConnect(GetEntityId()); + AzFramework::BoundsRequestBus::Handler::BusConnect(GetEntityId()); + AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusConnect(); + + } + + void TerrainWorldDebuggerComponent::Deactivate() + { + TerrainSystemServiceRequestBus::Broadcast( + &TerrainSystemServiceRequestBus::Events::SetDebugWireframe, false); + + AzFramework::Terrain::TerrainDataNotificationBus::Handler::BusDisconnect(); + AzFramework::BoundsRequestBus::Handler::BusDisconnect(); + AzFramework::EntityDebugDisplayEventBus::Handler::BusDisconnect(); + + m_wireframeBounds = AZ::Aabb::CreateNull(); + m_wireframeSectors.clear(); + } + + bool TerrainWorldDebuggerComponent::ReadInConfig(const AZ::ComponentConfig* baseConfig) + { + if (auto config = azrtti_cast(baseConfig)) + { + m_configuration = *config; + return true; + } + return false; + } + + bool TerrainWorldDebuggerComponent::WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const + { + if (auto config = azrtti_cast(outBaseConfig)) + { + *config = m_configuration; + return true; + } + return false; + } + + AZ::Aabb TerrainWorldDebuggerComponent::GetWorldBounds() + { + AZ::Aabb terrainAabb = AZ::Aabb::CreateFromPoint(AZ::Vector3::CreateZero()); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + terrainAabb, &AzFramework::Terrain::TerrainDataRequests::GetTerrainAabb); + + return terrainAabb; + } + + AZ::Aabb TerrainWorldDebuggerComponent::GetLocalBounds() + { + // This is a level component, so the local bounds will always be the same as the world bounds. + return GetWorldBounds(); + } + + void TerrainWorldDebuggerComponent::DisplayEntityViewport( + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) + { + // Draw a wireframe box around the entire terrain world bounds + if (m_configuration.m_drawWorldBounds) + { + AZ::Color outlineColor(1.0f, 0.0f, 0.0f, 1.0f); + AZ::Aabb aabb = GetWorldBounds(); + + debugDisplay.SetColor(outlineColor); + debugDisplay.DrawWireBox(aabb.GetMin(), aabb.GetMax()); + } + + // Draw a wireframe representation of the terrain surface + if (m_configuration.m_drawWireframe && !m_wireframeSectors.empty()) + { + // Start by assuming we'll draw the entire world. + AZ::Aabb drawingAabb = GetWorldBounds(); + + // Assuming we can get the camera, reduce the drawing bounds to a fixed distance around the camera. + if (auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); viewportContextRequests) + { + // Get the current camera position. + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetViewportContextById(viewportInfo.m_viewportId); + AZ::Vector3 cameraPos = viewportContext->GetCameraTransform().GetTranslation(); + + // Determine how far to draw in each direction in world space based on our MaxSectorsToDraw + AZ::Vector2 queryResolution = AZ::Vector2(1.0f); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + queryResolution, &AzFramework::Terrain::TerrainDataRequests::GetTerrainGridResolution); + AZ::Vector3 viewDistance( + queryResolution.GetX() * SectorSizeInGridPoints * sqrtf(MaxSectorsToDraw), + queryResolution.GetY() * SectorSizeInGridPoints * sqrtf(MaxSectorsToDraw), + 0.0f); + + // Create an AABB around the camera based on how far we want to be able to draw in each direction and clamp the + // drawing AABB to it. + AZ::Aabb cameraAabb = AZ::Aabb::CreateFromMinMax( + AZ::Vector3( + cameraPos.GetX() - viewDistance.GetX(), cameraPos.GetY() - viewDistance.GetY(), drawingAabb.GetMin().GetZ()), + AZ::Vector3( + cameraPos.GetX() + viewDistance.GetX(), cameraPos.GetY() + viewDistance.GetY(), drawingAabb.GetMin().GetZ())); + drawingAabb.Clamp(cameraAabb); + } + + // For each sector, if it appears within our view distance, draw it. + for (auto& sector : m_wireframeSectors) + { + if (drawingAabb.Overlaps(sector.m_aabb)) + { + if (!sector.m_lineVertices.empty()) + { + const AZ::Color primaryColor = AZ::Color(0.25f, 0.25f, 0.25f, 1.0f); + debugDisplay.DrawLines(sector.m_lineVertices, primaryColor); + } + else + { + AZ_Warning("Debug", false, "empty sector!"); + } + } + } + } + } + + void TerrainWorldDebuggerComponent::RefreshCachedWireframeGrid(const AZ::Aabb& dirtyRegion) + { + // Get the terrain world bounds and grid resolution. + + AZ::Aabb worldBounds = GetWorldBounds(); + + AZ::Vector2 queryResolution = AZ::Vector2(1.0f); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + queryResolution, &AzFramework::Terrain::TerrainDataRequests::GetTerrainGridResolution); + + // Calculate the world size of each sector. Note that this size actually ends at the last point, not the last square. + // So for example, the sector size for 3 points will go from (*--*--*) even though it will be used to draw (*--*--*--). + const float xSectorSize = (queryResolution.GetX() * SectorSizeInGridPoints); + const float ySectorSize = (queryResolution.GetY() * SectorSizeInGridPoints); + + // Calculate the total number of sectors to cache. The world bounds might not be evenly divisible by sector bounds, so we add + // an extra sector's worth of size in each direction so that clamping down to an integer still accounts for that fractional sector. + const int32_t numSectorsX = aznumeric_cast((worldBounds.GetXExtent() + xSectorSize) / xSectorSize); + const int32_t numSectorsY = aznumeric_cast((worldBounds.GetYExtent() + ySectorSize) / ySectorSize); + + // If we haven't cached anything before, or if the world bounds has changed, clear our cache structure and repopulate it + // with WireframeSector entries with the proper AABB sizes. + if (!m_wireframeBounds.IsValid() || !dirtyRegion.IsValid() || !m_wireframeBounds.IsClose(worldBounds)) + { + m_wireframeBounds = worldBounds; + + m_wireframeSectors.clear(); + m_wireframeSectors.reserve(numSectorsX * numSectorsY); + + for (int32_t ySector = 0; ySector < numSectorsY; ySector++) + { + for (int32_t xSector = 0; xSector < numSectorsX; xSector++) + { + // For each sector, set up the AABB for the sector and reserve memory for the line vertices. + WireframeSector sector; + sector.m_lineVertices.reserve(VerticesPerSector); + sector.m_aabb = AZ::Aabb::CreateFromMinMax( + AZ::Vector3( + worldBounds.GetMin().GetX() + (xSector * xSectorSize), worldBounds.GetMin().GetY() + (ySector * ySectorSize), + worldBounds.GetMin().GetZ()), + AZ::Vector3( + worldBounds.GetMin().GetX() + ((xSector + 1) * xSectorSize), + worldBounds.GetMin().GetY() + ((ySector + 1) * ySectorSize), worldBounds.GetMax().GetZ())); + + sector.m_aabb.Clamp(worldBounds); + + m_wireframeSectors.push_back(AZStd::move(sector)); + } + } + + // Notify the visibility system that our bounds have changed. + AzFramework::IEntityBoundsUnionRequestBus::Broadcast( + &AzFramework::IEntityBoundsUnionRequestBus::Events::RefreshEntityLocalBoundsUnion, GetEntityId()); + } + + // For each sector, if it overlaps with the dirty region, clear it out and recache the wireframe line data. + for (auto& sector : m_wireframeSectors) + { + if (dirtyRegion.IsValid() && !dirtyRegion.Overlaps(sector.m_aabb)) + { + continue; + } + + sector.m_lineVertices.clear(); + + for (float y = sector.m_aabb.GetMin().GetY(); y < sector.m_aabb.GetMax().GetY(); y += queryResolution.GetY()) + { + for (float x = sector.m_aabb.GetMin().GetX(); x < sector.m_aabb.GetMax().GetX(); x += queryResolution.GetX()) + { + float x1 = x + queryResolution.GetX(); + float y1 = y + queryResolution.GetY(); + + float z00 = 0.0f; + float z01 = 0.0f; + float z10 = 0.0f; + bool terrainExists; + + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + z00, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y, + AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, &terrainExists); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + z01, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x, y1, + AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, &terrainExists); + AzFramework::Terrain::TerrainDataRequestBus::BroadcastResult( + z10, &AzFramework::Terrain::TerrainDataRequests::GetHeightFromFloats, x1, y, + AzFramework::Terrain::TerrainDataRequests::Sampler::DEFAULT, &terrainExists); + + sector.m_lineVertices.push_back(AZ::Vector3(x, y, z00)); + sector.m_lineVertices.push_back(AZ::Vector3(x1, y, z10)); + + sector.m_lineVertices.push_back(AZ::Vector3(x, y, z00)); + sector.m_lineVertices.push_back(AZ::Vector3(x, y1, z01)); + } + } + } + } + + void TerrainWorldDebuggerComponent::OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) + { + if (dataChangedMask & (TerrainDataChangedMask::Settings | TerrainDataChangedMask::HeightData)) + { + RefreshCachedWireframeGrid(dirtyRegion); + } + } + + +} // namespace Terrain diff --git a/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h new file mode 100644 index 0000000000..5ec831c038 --- /dev/null +++ b/Gems/Terrain/Code/Source/Components/TerrainWorldDebuggerComponent.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace LmbrCentral +{ + template + class EditorWrappedComponentBase; +} + +namespace Terrain +{ + class TerrainWorldDebuggerConfig + : public AZ::ComponentConfig + { + public: + AZ_CLASS_ALLOCATOR(TerrainWorldDebuggerConfig, AZ::SystemAllocator, 0); + AZ_RTTI(TerrainWorldDebuggerConfig, "{92686FA9-2C0B-47F1-8E2D-F2F302CDE5AA}", AZ::ComponentConfig); + static void Reflect(AZ::ReflectContext* context); + + bool m_drawWireframe{ true }; + bool m_drawWorldBounds{ true }; + }; + + + class TerrainWorldDebuggerComponent + : public AZ::Component + , private AzFramework::EntityDebugDisplayEventBus::Handler + , private AzFramework::BoundsRequestBus::Handler + , private AzFramework::Terrain::TerrainDataNotificationBus::Handler + { + public: + template + friend class LmbrCentral::EditorWrappedComponentBase; + AZ_COMPONENT(TerrainWorldDebuggerComponent, "{ECA1F4CB-5395-41FD-B6ED-FFD2C80096E2}"); + static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& services); + static void Reflect(AZ::ReflectContext* context); + + TerrainWorldDebuggerComponent(const TerrainWorldDebuggerConfig& configuration); + TerrainWorldDebuggerComponent() = default; + ~TerrainWorldDebuggerComponent() override; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override; + bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override; + + ////////////////////////////////////////////////////////////////////////// + // EntityDebugDisplayEventBus + + // Ideally this would use ViewportDebugDisplayEventBus::DisplayViewport, but that doesn't currently work in game mode, + // so instead we use this plus the BoundsRequestBus with a large AABB to get ourselves rendered. + void DisplayEntityViewport( + const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; + + ////////////////////////////////////////////////////////////////////////// + // BoundsRequestBus + AZ::Aabb GetWorldBounds() override; + AZ::Aabb GetLocalBounds() override; + + ////////////////////////////////////////////////////////////////////////// + // AzFramework::Terrain::TerrainDataNotificationBus + void OnTerrainDataChanged(const AZ::Aabb& dirtyRegion, TerrainDataChangedMask dataChangedMask) override; + + private: + + // Cache our debug wireframe representation in "sectors" of data so that we can easily control how far out we draw + // the wireframe representation in each direction. + struct WireframeSector + { + AZ::Aabb m_aabb; + AZStd::vector m_lineVertices; + }; + + // Each sector contains an N x N grid of squares that it will draw. Since this is a count of the number of terrain grid points + // in each direction, the actual world size will depend on the terrain grid resolution in each direction. + static constexpr int32_t SectorSizeInGridPoints = 10; + + // For each grid point we will draw half a square (left-right, top-down), so we need 4 vertices for the two lines. + static constexpr int32_t VerticesPerGridPoint = 4; + + // Pre-calculate the total number of vertices per sector. + static constexpr int32_t VerticesPerSector = + (SectorSizeInGridPoints * VerticesPerGridPoint) * (SectorSizeInGridPoints * VerticesPerGridPoint); + + // AuxGeom has limits to the number of lines it can draw in a frame, so we'll cap how many total sectors to draw. + static constexpr int32_t MaxVerticesToDraw = 500000; + static constexpr int32_t MaxSectorsToDraw = MaxVerticesToDraw / VerticesPerSector; + + void RefreshCachedWireframeGrid(const AZ::Aabb& dirtyRegion); + + TerrainWorldDebuggerConfig m_configuration; + AZStd::vector m_wireframeSectors; + AZ::Aabb m_wireframeBounds; + }; +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.cpp b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.cpp new file mode 100644 index 0000000000..8a36445446 --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace Terrain +{ + void EditorTerrainHeightGradientListComponent::Reflect(AZ::ReflectContext* context) + { + BaseClassType::ReflectSubClass(context, 1, + &LmbrCentral::EditorWrappedComponentBaseVersionConverter + ); + } +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.h b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.h new file mode 100644 index 0000000000..2433eda009 --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainHeightGradientListComponent.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace Terrain +{ + class EditorTerrainHeightGradientListComponent + : public LmbrCentral::EditorWrappedComponentBase + { + public: + using BaseClassType = LmbrCentral::EditorWrappedComponentBase; + AZ_EDITOR_COMPONENT(EditorTerrainHeightGradientListComponent, "{2D945B90-ADAB-4F9A-A113-39E714708068}", BaseClassType); + static void Reflect(AZ::ReflectContext* context); + + static constexpr const char* const s_categoryName = "Terrain"; + static constexpr const char* const s_componentName = "Terrain Height Gradient List"; + static constexpr const char* const s_componentDescription = "Provides height data for a region to the terrain system"; + static constexpr const char* const s_icon = "Editor/Icons/Components/TerrainHeight.svg"; + static constexpr const char* const s_viewportIcon = "Editor/Icons/Components/Viewport/TerrainHeight.svg"; + static constexpr const char* const s_helpUrl = ""; + }; +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp new file mode 100644 index 0000000000..3a0208aece --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace Terrain +{ + void EditorTerrainLayerSpawnerComponent::Reflect(AZ::ReflectContext* context) + { + BaseClassType::ReflectSubClass(context, 1, + &LmbrCentral::EditorWrappedComponentBaseVersionConverter + ); + } +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h new file mode 100644 index 0000000000..1eb3413d52 --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace Terrain +{ + class EditorTerrainLayerSpawnerComponent + : public LmbrCentral::EditorWrappedComponentBase + { + public: + using BaseClassType = LmbrCentral::EditorWrappedComponentBase; + AZ_EDITOR_COMPONENT(EditorTerrainLayerSpawnerComponent, "{9403FC94-FA38-4387-BEFD-A728C7D850C1}", BaseClassType); + static void Reflect(AZ::ReflectContext* context); + + static constexpr const char* const s_categoryName = "Terrain"; + static constexpr const char* const s_componentName = "Terrain Layer Spawner"; + static constexpr const char* const s_componentDescription = "Defines a terrain region for use by the terrain system"; + static constexpr const char* const s_icon = "Editor/Icons/Components/TerrainLayerSpawner.svg"; + static constexpr const char* const s_viewportIcon = "Editor/Icons/Components/Viewport/TerrainLayerSpawner.svg"; + static constexpr const char* const s_helpUrl = ""; + }; +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.cpp b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.cpp new file mode 100644 index 0000000000..a50a44745f --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace Terrain +{ + void EditorTerrainWorldComponent::Reflect(AZ::ReflectContext* context) + { + BaseClassType::Reflect(context); + + AZ::SerializeContext* serializeContext = azrtti_cast(context); + + if (serializeContext) + { + serializeContext->Class() + ->Version(0) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "Terrain World", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Category, "Terrain") + ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/TerrainWorld.svg") + ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/TerrainWorld.svg") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector({ AZ_CRC_CE("Level") })) + ; + } + } + } + + + void EditorTerrainWorldComponent::Init() + { + BaseClassType::Init(); + } + + void EditorTerrainWorldComponent::Activate() + { + BaseClassType::Activate(); + } + + AZ::u32 EditorTerrainWorldComponent::ConfigurationChanged() + { + return BaseClassType::ConfigurationChanged(); + } +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.h b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.h new file mode 100644 index 0000000000..6f3ab73361 --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldComponent.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace Terrain +{ + class EditorTerrainWorldComponent + : public LmbrCentral::EditorWrappedComponentBase + { + public: + using BaseClassType = LmbrCentral::EditorWrappedComponentBase; + AZ_EDITOR_COMPONENT(EditorTerrainWorldComponent, "{43D02ADC-111F-4584-B590-FF6DC9FC912C}", BaseClassType); + static void Reflect(AZ::ReflectContext* context); + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Init() override; + void Activate() override; + AZ::u32 ConfigurationChanged() override; + + protected: + using BaseClassType::m_configuration; + using BaseClassType::m_component; + using BaseClassType::m_visible; + + private: + }; +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp new file mode 100644 index 0000000000..7e8fbf58e4 --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include + +namespace Terrain +{ + void EditorTerrainWorldDebuggerComponent::Reflect(AZ::ReflectContext* context) + { + BaseClassType::Reflect(context); + + AZ::SerializeContext* serializeContext = azrtti_cast(context); + + if (serializeContext) + { + serializeContext->Class() + ->Version(0) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class( + "Terrain World Debugger", "") + ->ClassElement(AZ::Edit::ClassElements::EditorData, "") + ->Attribute(AZ::Edit::Attributes::Category, "Terrain") + ->Attribute(AZ::Edit::Attributes::Icon, "Editor/Icons/Components/TerrainWorldDebugger.svg") + ->Attribute(AZ::Edit::Attributes::ViewportIcon, "Editor/Icons/Components/Viewport/TerrainWorldDebugger.svg") + ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZStd::vector({ AZ_CRC_CE("Level") })) + ; + } + } + } + + + void EditorTerrainWorldDebuggerComponent::Init() + { + BaseClassType::Init(); + } + + void EditorTerrainWorldDebuggerComponent::Activate() + { + BaseClassType::Activate(); + } + + AZ::u32 EditorTerrainWorldDebuggerComponent::ConfigurationChanged() + { + return BaseClassType::ConfigurationChanged(); + } +} diff --git a/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.h b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.h new file mode 100644 index 0000000000..ddcfe3c76a --- /dev/null +++ b/Gems/Terrain/Code/Source/EditorComponents/EditorTerrainWorldDebuggerComponent.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace Terrain +{ + class EditorTerrainWorldDebuggerComponent + : public LmbrCentral::EditorWrappedComponentBase + { + public: + using BaseClassType = LmbrCentral::EditorWrappedComponentBase; + AZ_EDITOR_COMPONENT(EditorTerrainWorldDebuggerComponent, "{D09BA0B9-FB51-446B-BD7B-3C40743D2E39}", BaseClassType); + static void Reflect(AZ::ReflectContext* context); + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Init() override; + void Activate() override; + AZ::u32 ConfigurationChanged() override; + + protected: + using BaseClassType::m_configuration; + using BaseClassType::m_component; + using BaseClassType::m_visible; + + private: + }; +} diff --git a/Gems/Terrain/Code/Source/EditorTerrainModule.cpp b/Gems/Terrain/Code/Source/EditorTerrainModule.cpp index bd4c94f4bf..0ba416cbb7 100644 --- a/Gems/Terrain/Code/Source/EditorTerrainModule.cpp +++ b/Gems/Terrain/Code/Source/EditorTerrainModule.cpp @@ -7,7 +7,11 @@ */ #include +#include +#include #include +#include +#include namespace Terrain { @@ -16,7 +20,12 @@ namespace Terrain m_descriptors.insert( m_descriptors.end(), { + Terrain::EditorTerrainHeightGradientListComponent::CreateDescriptor(), + Terrain::EditorTerrainLayerSpawnerComponent::CreateDescriptor(), Terrain::EditorTerrainSystemComponent::CreateDescriptor(), + Terrain::EditorTerrainWorldComponent::CreateDescriptor(), + Terrain::EditorTerrainWorldDebuggerComponent::CreateDescriptor(), + }); } diff --git a/Gems/Terrain/Code/Source/TerrainModule.cpp b/Gems/Terrain/Code/Source/TerrainModule.cpp index ec9325eb5c..29b2542472 100644 --- a/Gems/Terrain/Code/Source/TerrainModule.cpp +++ b/Gems/Terrain/Code/Source/TerrainModule.cpp @@ -11,6 +11,10 @@ #include #include +#include +#include +#include +#include #include namespace Terrain @@ -20,6 +24,10 @@ namespace Terrain { m_descriptors.insert(m_descriptors.end(), { TerrainSystemComponent::CreateDescriptor(), + TerrainWorldComponent::CreateDescriptor(), + TerrainWorldDebuggerComponent::CreateDescriptor(), + TerrainHeightGradientListComponent::CreateDescriptor(), + TerrainLayerSpawnerComponent::CreateDescriptor(), TerrainSurfaceDataSystemComponent::CreateDescriptor(), }); } diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp new file mode 100644 index 0000000000..5af3fd58b9 --- /dev/null +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.cpp @@ -0,0 +1,490 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace Terrain +{ + namespace + { + const uint32_t DEFAULT_UploadBufferSize = 512 * 1024; // 512k + } + + namespace ShaderInputs + { + static const char* const HeightmapImage("HeightmapImage"); + static const char* const ModelToWorld("m_modelToWorld"); + static const char* const HeightScale("m_heightScale"); + static const char* const UvMin("m_uvMin"); + static const char* const UvMax("m_uvMax"); + static const char* const UvStep("m_uvStep"); + } + + + void TerrainFeatureProcessor::Reflect(AZ::ReflectContext* context) + { + if (AZ::SerializeContext* serialize = azrtti_cast(context)) + { + serialize->Class() + ->Version(0) + ; + } + } + + void TerrainFeatureProcessor::Activate() + { + m_areaData.clear(); + + InitializeAtomStuff(); + EnableSceneNotification(); + } + + void TerrainFeatureProcessor::InitializeAtomStuff() + { + m_rhiSystem = AZ::RHI::RHISystemInterface::Get(); + + m_rhiSystem->GetDrawListTagRegistry()->AcquireTag(AZ::Name("Terrain")); + + { + // Load the shader + + const char* terrainShaderFilePath = "Shaders/Terrain/Terrain.azshader"; + + AZ::Data::AssetId shaderAssetId; + AZ::Data::AssetCatalogRequestBus::BroadcastResult( + shaderAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, + terrainShaderFilePath, azrtti_typeid(), false); + if (!shaderAssetId.IsValid()) + { + AZ_Error("Terrain", false, "Failed to get shader asset id with path %s", terrainShaderFilePath); + return; + } + + auto shaderAsset = AZ::Data::AssetManager::Instance().GetAsset(shaderAssetId, AZ::Data::AssetLoadBehavior::PreLoad); + shaderAsset.BlockUntilLoadComplete(); + + if (!shaderAsset.IsReady()) + { + AZ_Error("Terrain", false, "Failed to get shader asset with path %s", terrainShaderFilePath); + return; + } + + m_shader = AZ::RPI::Shader::FindOrCreate(shaderAsset); + if (!m_shader) + { + AZ_Error("Terrain", false, "Failed to find or create a shader instance from shader asset '%s'", terrainShaderFilePath); + return; + } + + // Create the data layout + + m_pipelineStateDescriptor = AZ::RHI::PipelineStateDescriptorForDraw{}; + + { + AZ::RHI::InputStreamLayoutBuilder layoutBuilder; + + layoutBuilder.AddBuffer() + ->Channel("POSITION", AZ::RHI::Format::R32G32_FLOAT) + ->Channel("UV", AZ::RHI::Format::R32G32_FLOAT) + ; + m_pipelineStateDescriptor.m_inputStreamLayout = layoutBuilder.End(); + } + + auto shaderVariant = m_shader->GetVariant(AZ::RPI::ShaderAsset::RootShaderVariantStableId); + shaderVariant.ConfigurePipelineState(m_pipelineStateDescriptor); + + m_drawListTag = m_shader->GetDrawListTag(); + + m_perObjectSrgAsset = m_shader->FindShaderResourceGroupLayout(AZ::Name{"ObjectSrg"}); + if (!m_perObjectSrgAsset) + { + AZ_Error("Terrain", false, "Failed to get shader resource group asset"); + return; + } + else if (!m_perObjectSrgAsset->IsFinalized()) + { + AZ_Error("Terrain", false, "Shader resource group asset is not loaded"); + return; + } + + const AZ::RHI::ShaderResourceGroupLayout* shaderResourceGroupLayout = &(*m_perObjectSrgAsset); + + m_heightmapImageIndex = shaderResourceGroupLayout->FindShaderInputImageIndex(AZ::Name(ShaderInputs::HeightmapImage)); + AZ_Error("Terrain", m_heightmapImageIndex.IsValid(), "Failed to find shader input image %s.", ShaderInputs::HeightmapImage); + + m_modelToWorldIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::ModelToWorld)); + AZ_Error("Terrain", m_modelToWorldIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::ModelToWorld); + + m_heightScaleIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::HeightScale)); + AZ_Error("Terrain", m_heightScaleIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::HeightScale); + + m_uvMinIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvMin)); + AZ_Error("Terrain", m_uvMinIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMin); + + m_uvMaxIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvMax)); + AZ_Error("Terrain", m_uvMaxIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvMax); + + m_uvStepIndex = shaderResourceGroupLayout->FindShaderInputConstantIndex(AZ::Name(ShaderInputs::UvStep)); + AZ_Error("Terrain", m_uvStepIndex.IsValid(), "Failed to find shader input constant %s.", ShaderInputs::UvStep); + + // If this fails to run now, it's ok, we'll initialize it in OnRenderPipelineAdded later. + bool success = GetParentScene()->ConfigurePipelineState(m_shader->GetDrawListTag(), m_pipelineStateDescriptor); + if (success) + { + m_pipelineState = m_shader->AcquirePipelineState(m_pipelineStateDescriptor); + AZ_Assert(m_pipelineState, "Failed to acquire default pipeline state for shader '%s'", terrainShaderFilePath); + } + } + + AZ::RHI::BufferPoolDescriptor dmaPoolDescriptor; + dmaPoolDescriptor.m_heapMemoryLevel = AZ::RHI::HeapMemoryLevel::Host; + dmaPoolDescriptor.m_bindFlags = AZ::RHI::BufferBindFlags::InputAssembly; + + m_hostPool = AZ::RHI::Factory::Get().CreateBufferPool(); + m_hostPool->SetName(AZ::Name("TerrainVertexPool")); + AZ::RHI::ResultCode resultCode = m_hostPool->Init(*m_rhiSystem->GetDevice(), dmaPoolDescriptor); + + if (resultCode != AZ::RHI::ResultCode::Success) + { + AZ_Error("Terrain", false, "Failed to create host buffer pool from RPI"); + return; + } + + InitializeTerrainPatch(); + + if (!InitializeRenderBuffers()) + { + AZ_Error("Terrain", false, "Failed to create Terrain render buffers!"); + return; + } + } + + void TerrainFeatureProcessor::OnRenderPipelineAdded([[maybe_unused]] AZ::RPI::RenderPipelinePtr pipeline) + { + bool success = GetParentScene()->ConfigurePipelineState(m_drawListTag, m_pipelineStateDescriptor); + AZ_Assert(success, "Couldn't configure the pipeline state."); + if (success) + { + m_pipelineState = m_shader->AcquirePipelineState(m_pipelineStateDescriptor); + AZ_Assert(m_pipelineState, "Failed to acquire default pipeline state."); + } + } + + void TerrainFeatureProcessor::OnRenderPipelineRemoved([[maybe_unused]] AZ::RPI::RenderPipeline* pipeline) + { + } + + void TerrainFeatureProcessor::OnRenderPipelinePassesChanged([[maybe_unused]] AZ::RPI::RenderPipeline* renderPipeline) + { + } + + + void TerrainFeatureProcessor::Deactivate() + { + DisableSceneNotification(); + + DestroyRenderBuffers(); + m_areaData.clear(); + + if (m_hostPool) + { + m_hostPool.reset(); + } + + m_rhiSystem = nullptr; + } + + void TerrainFeatureProcessor::Render(const AZ::RPI::FeatureProcessor::RenderPacket& packet) + { + ProcessSurfaces(packet); + } + + void TerrainFeatureProcessor::UpdateTerrainData( + AZ::EntityId areaId, + const AZ::Transform& transform, + const AZ::Aabb& worldBounds, + [[maybe_unused]] float sampleSpacing, + uint32_t width, uint32_t height, const AZStd::vector& heightData) + { + if (!worldBounds.IsValid()) + { + m_areaData.erase(areaId); + return; + } + + TerrainAreaData areaData; + + areaData.m_transform = transform; + areaData.m_heightScale = worldBounds.GetZExtent(); + areaData.m_terrainBounds = worldBounds; + areaData.m_heightmapImageHeight = height; + areaData.m_heightmapImageWidth = width; + + // Create heightmap image data + { + areaData.m_propertiesDirty = true; + + AZ::RHI::Size imageSize; + imageSize.m_width = width; + imageSize.m_height = height; + + AZ::Data::Instance streamingImagePool = AZ::RPI::ImageSystemInterface::Get()->GetSystemStreamingPool(); + areaData.m_heightmapImage = AZ::RPI::StreamingImage::CreateFromCpuData(*streamingImagePool, + AZ::RHI::ImageDimension::Image2D, + imageSize, + AZ::RHI::Format::R32_FLOAT, + (uint8_t*)heightData.data(), + heightData.size() * sizeof(float)); + AZ_Error("Terrain", areaData.m_heightmapImage, "Failed to initialize the heightmap image!"); + } + + m_areaData.insert_or_assign(areaId, areaData); + } + + void TerrainFeatureProcessor::ProcessSurfaces(const FeatureProcessor::RenderPacket& process) + { + AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender); + + if (m_drawListTag.IsNull()) + { + return; + } + + if (m_areaData.empty()) + { + return; + } + + m_drawPackets.clear(); + m_processSrgs.clear(); + + AZ::RHI::DrawPacketBuilder drawPacketBuilder; + + uint32_t numIndices = static_cast(m_gridIndices.size()); + + AZ::RHI::DrawIndexed drawIndexed; + drawIndexed.m_indexCount = numIndices; + drawIndexed.m_indexOffset = 0; + drawIndexed.m_vertexOffset = 0; + + for (auto& [areaId, areaData] : m_areaData) + { + float xFirstPatchStart = + areaData.m_terrainBounds.GetMin().GetX() - fmod(areaData.m_terrainBounds.GetMin().GetX(), m_gridMeters); + float xLastPatchStart = areaData.m_terrainBounds.GetMax().GetX() - fmod(areaData.m_terrainBounds.GetMax().GetX(), m_gridMeters); + float yFirstPatchStart = + areaData.m_terrainBounds.GetMin().GetY() - fmod(areaData.m_terrainBounds.GetMin().GetY(), m_gridMeters); + float yLastPatchStart = areaData.m_terrainBounds.GetMax().GetY() - fmod(areaData.m_terrainBounds.GetMax().GetY(), m_gridMeters); + + for (float yPatch = yFirstPatchStart; yPatch <= yLastPatchStart; yPatch += m_gridMeters) + { + for (float xPatch = xFirstPatchStart; xPatch <= xLastPatchStart; xPatch += m_gridMeters) + { + drawPacketBuilder.Begin(nullptr); + drawPacketBuilder.SetDrawArguments(drawIndexed); + drawPacketBuilder.SetIndexBufferView(m_indexBufferView); + + auto m_resourceGroup = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), AZ::Name("ObjectSrg")); + //auto m_resourceGroup = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), AZ::Name("ObjectSrg")); + if (!m_resourceGroup) + { + AZ_Error("Terrain", false, "Failed to create shader resource group"); + return; + } + + float uvMin[2] = { 0.0f, 0.0f }; + float uvMax[2] = { 1.0f, 1.0f }; + + uvMin[0] = (float)((xPatch - areaData.m_terrainBounds.GetMin().GetX()) / areaData.m_terrainBounds.GetXExtent()); + uvMin[1] = (float)((yPatch - areaData.m_terrainBounds.GetMin().GetY()) / areaData.m_terrainBounds.GetYExtent()); + + uvMax[0] = + (float)(((xPatch + m_gridMeters) - areaData.m_terrainBounds.GetMin().GetX()) / areaData.m_terrainBounds.GetXExtent()); + uvMax[1] = + (float)(((yPatch + m_gridMeters) - areaData.m_terrainBounds.GetMin().GetY()) / areaData.m_terrainBounds.GetYExtent()); + + float uvStep[2] = + { + 1.0f / areaData.m_heightmapImageWidth, 1.0f / areaData.m_heightmapImageHeight, + }; + + AZ::Transform transform = areaData.m_transform; + transform.SetTranslation(xPatch, yPatch, areaData.m_transform.GetTranslation().GetZ()); + + AZ::Matrix3x4 matrix3x4 = AZ::Matrix3x4::CreateFromTransform(transform); + + m_resourceGroup->SetImage(m_heightmapImageIndex, areaData.m_heightmapImage); + m_resourceGroup->SetConstant(m_modelToWorldIndex, matrix3x4); + m_resourceGroup->SetConstant(m_heightScaleIndex, areaData.m_heightScale); + m_resourceGroup->SetConstant(m_uvMinIndex, uvMin); + m_resourceGroup->SetConstant(m_uvMaxIndex, uvMax); + m_resourceGroup->SetConstant(m_uvStepIndex, uvStep); + m_resourceGroup->Compile(); + m_processSrgs.push_back(m_resourceGroup); + + if (m_resourceGroup != nullptr) + { + drawPacketBuilder.AddShaderResourceGroup(m_resourceGroup->GetRHIShaderResourceGroup()); + } + + AZ::RHI::DrawPacketBuilder::DrawRequest drawRequest; + drawRequest.m_listTag = m_drawListTag; + drawRequest.m_pipelineState = m_pipelineState.get(); + drawRequest.m_streamBufferViews = m_vertexBufferViews; + drawPacketBuilder.AddDrawItem(drawRequest); + + const AZ::RHI::DrawPacket* drawPacket = drawPacketBuilder.End(); + m_drawPackets.emplace_back(drawPacket); + + for (auto& view : process.m_views) + { + view->AddDrawPacket(drawPacket); + } + } + } + } + } + + void TerrainFeatureProcessor::InitializeTerrainPatch() + { + m_gridVertices.clear(); + m_gridIndices.clear(); + + for (float y = 0.0f; y < m_gridMeters; y += m_gridSpacing) + { + for (float x = 0.0f; x < m_gridMeters; x += m_gridSpacing) + { + float x0 = x; + float x1 = x + m_gridSpacing; + float y0 = y; + float y1 = y + m_gridSpacing; + + uint16_t startIndex = (uint16_t)(m_gridVertices.size()); + + m_gridVertices.emplace_back(x0, y0, x0 / m_gridMeters, y0 / m_gridMeters); + m_gridVertices.emplace_back(x0, y1, x0 / m_gridMeters, y1 / m_gridMeters); + m_gridVertices.emplace_back(x1, y0, x1 / m_gridMeters, y0 / m_gridMeters); + m_gridVertices.emplace_back(x1, y1, x1 / m_gridMeters, y1 / m_gridMeters); + + m_gridIndices.emplace_back(startIndex); + m_gridIndices.emplace_back(aznumeric_cast(startIndex + 1)); + m_gridIndices.emplace_back(aznumeric_cast(startIndex + 2)); + m_gridIndices.emplace_back(aznumeric_cast(startIndex + 1)); + m_gridIndices.emplace_back(aznumeric_cast(startIndex + 2)); + m_gridIndices.emplace_back(aznumeric_cast(startIndex + 3)); + } + } + } + + bool TerrainFeatureProcessor::InitializeRenderBuffers() + { + AZ::RHI::ResultCode result = AZ::RHI::ResultCode::Fail; + + // Create geometry buffers + m_indexBuffer = AZ::RHI::Factory::Get().CreateBuffer(); + m_vertexBuffer = AZ::RHI::Factory::Get().CreateBuffer(); + + m_indexBuffer->SetName(AZ::Name("TerrainIndexBuffer")); + m_vertexBuffer->SetName(AZ::Name("TerrainVertexBuffer")); + + // We only need one vertex buffer view. + m_vertexBufferViews.resize(1); + + AZStd::vector> buffers = { m_indexBuffer , m_vertexBuffer }; + + // Fill our buffers with the vertex/index data + for (size_t bufferIndex = 0; bufferIndex < buffers.size(); ++bufferIndex) + { + AZ::RHI::Ptr buffer = buffers[bufferIndex]; + + // Initialize the buffer + + AZ::RHI::BufferInitRequest bufferRequest; + bufferRequest.m_descriptor = AZ::RHI::BufferDescriptor{ AZ::RHI::BufferBindFlags::InputAssembly, DEFAULT_UploadBufferSize }; + bufferRequest.m_buffer = buffer.get(); + + result = m_hostPool->InitBuffer(bufferRequest); + + if (result != AZ::RHI::ResultCode::Success) + { + AZ_Error("Terrain", false, "Failed to create GPU buffers for Terrain"); + return false; + } + + // Grab a pointer to the buffer's data + + m_hostPool->OrphanBuffer(*buffer); + + AZ::RHI::BufferMapResponse mapResponse; + m_hostPool->MapBuffer(AZ::RHI::BufferMapRequest(*buffer, 0, DEFAULT_UploadBufferSize), mapResponse); + + auto* mappedData = reinterpret_cast(mapResponse.m_data); + + //0th index should always be the index buffer + if (bufferIndex == 0) + { + // Fill the index buffer with our terrain patch indices + const uint64_t idxSize = m_gridIndices.size() * sizeof(uint16_t); + memcpy(mappedData, m_gridIndices.data(), idxSize); + + m_indexBufferView = AZ::RHI::IndexBufferView( + *buffer, 0, static_cast(idxSize), AZ::RHI::IndexFormat::Uint16); + } + else + { + // Fill the vertex buffer with our terrain patch vertices + const uint64_t elementSize = m_gridVertices.size() * sizeof(Vertex); + memcpy(mappedData, m_gridVertices.data(), elementSize); + + m_vertexBufferViews[bufferIndex - 1] = AZ::RHI::StreamBufferView( + *buffer, 0, static_cast(elementSize), static_cast(sizeof(Vertex))); + + AZ::RHI::ValidateStreamBufferViews(m_pipelineStateDescriptor.m_inputStreamLayout, m_vertexBufferViews); + } + + m_hostPool->UnmapBuffer(*buffer); + } + + return true; + } + + void TerrainFeatureProcessor::DestroyRenderBuffers() + { + m_indexBuffer.reset(); + m_vertexBuffer.reset(); + + m_vertexBufferViews.clear(); + + m_processSrgs.clear(); + + m_pipelineStateDescriptor = AZ::RHI::PipelineStateDescriptorForDraw{}; + m_pipelineState = nullptr; + } + +} diff --git a/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h new file mode 100644 index 0000000000..2a1d5b7514 --- /dev/null +++ b/Gems/Terrain/Code/Source/TerrainRenderer/TerrainFeatureProcessor.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Terrain +{ + class TerrainFeatureProcessor final + : public AZ::RPI::FeatureProcessor + { + public: + AZ_RTTI(TerrainFeatureProcessor, "{D7DAC1F9-4A9F-4D3C-80AE-99579BF8AB1C}", AZ::RPI::FeatureProcessor); + AZ_DISABLE_COPY_MOVE(TerrainFeatureProcessor); + AZ_FEATURE_PROCESSOR(TerrainFeatureProcessor); + + static void Reflect(AZ::ReflectContext* context); + + TerrainFeatureProcessor() = default; + ~TerrainFeatureProcessor() = default; + + ////////////////////////////////////////////////////////////////////////// + // AZ::Component interface implementation + void Activate() override; + void Deactivate() override; + void Render(const AZ::RPI::FeatureProcessor::RenderPacket& packet) override; + + void UpdateTerrainData(AZ::EntityId areaId, const AZ::Transform& transform, const AZ::Aabb& worldBounds, float sampleSpacing, + uint32_t width, uint32_t height, const AZStd::vector& heightData); + + void RemoveTerrainData(AZ::EntityId areaId) + { + m_areaData.erase(areaId); + } + void RemoveTerrainData() + { + m_areaData.clear(); + } + + private: + // RPI::SceneNotificationBus overrides ... + void OnRenderPipelineAdded(AZ::RPI::RenderPipelinePtr pipeline) override; + void OnRenderPipelineRemoved(AZ::RPI::RenderPipeline* pipeline) override; + void OnRenderPipelinePassesChanged(AZ::RPI::RenderPipeline* renderPipeline) override; + + void InitializeAtomStuff(); + + void InitializeTerrainPatch(); + + bool InitializeRenderBuffers(); + void DestroyRenderBuffers(); + + void ProcessSurfaces(const FeatureProcessor::RenderPacket& process); + + // System-level parameters + const float m_gridSpacing{ 1.0f }; + const float m_gridMeters{ 32.0f }; + + // System-level cached reference to the Atom RHI + AZ::RHI::RHISystemInterface* m_rhiSystem = nullptr; + + // System-level references to the shader, pipeline, and shader-related information + AZ::Data::Instance m_shader{}; + AZ::RHI::PipelineStateDescriptorForDraw m_pipelineStateDescriptor; + AZ::RHI::ConstPtr m_pipelineState = nullptr; + AZ::RHI::DrawListTag m_drawListTag; + AZ::RHI::Ptr m_perObjectSrgAsset; + + AZ::RHI::ShaderInputImageIndex m_heightmapImageIndex; + AZ::RHI::ShaderInputConstantIndex m_modelToWorldIndex; + AZ::RHI::ShaderInputConstantIndex m_heightScaleIndex; + AZ::RHI::ShaderInputConstantIndex m_uvMinIndex; + AZ::RHI::ShaderInputConstantIndex m_uvMaxIndex; + AZ::RHI::ShaderInputConstantIndex m_uvStepIndex; + + + // Pos_float_2 + UV_float_2 + struct Vertex + { + float m_posx; + float m_posy; + float m_u; + float m_v; + + Vertex(float posx, float posy, float u, float v) + : m_posx(posx) + , m_posy(posy) + , m_u(u) + , m_v(v) + { + } + }; + + // System-level definition of a grid patch. (ex: 32m x 32m) + AZStd::vector m_gridVertices; + AZStd::vector m_gridIndices; + + // System-level data related to the grid patch + AZ::RHI::Ptr m_hostPool = nullptr; + AZ::RHI::Ptr m_indexBuffer; + AZ::RHI::Ptr m_vertexBuffer; + AZ::RHI::IndexBufferView m_indexBufferView; + AZStd::fixed_vector m_vertexBufferViews; + + // Per-area data + struct TerrainAreaData + { + AZ::Transform m_transform; + AZ::Aabb m_terrainBounds; + float m_heightScale; + AZ::Data::Instance m_heightmapImage; + uint32_t m_heightmapImageWidth; + uint32_t m_heightmapImageHeight; + bool m_propertiesDirty{ true }; + }; + + AZStd::unordered_map m_areaData; + + // These could either be per-area or system-level + AZStd::vector> m_drawPackets; + AZStd::vector> m_processSrgs; + }; +} diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp new file mode 100644 index 0000000000..872b37a02e --- /dev/null +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.cpp @@ -0,0 +1,489 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include + +#include +#include +#include + +using namespace Terrain; + +TerrainSystem::TerrainSystem() +{ + Terrain::TerrainSystemServiceRequestBus::Handler::BusConnect(); + AZ::TickBus::Handler::BusConnect(); + + m_currentSettings.m_systemActive = false; + m_currentSettings.m_worldBounds = AZ::Aabb::CreateNull(); + + m_requestedSettings = m_currentSettings; + m_requestedSettings.m_worldBounds = AZ::Aabb::CreateFromMinMax(AZ::Vector3(0.0f, 0.0f, 0.0f), AZ::Vector3(4096.0f, 4096.0f, 2048.0f)); +} + +TerrainSystem::~TerrainSystem() +{ + AZ::TickBus::Handler::BusDisconnect(); + Terrain::TerrainSystemServiceRequestBus::Handler::BusDisconnect(); + + Deactivate(); +} + +void TerrainSystem::Activate() +{ + m_requestedSettings.m_systemActive = true; + m_terrainSettingsDirty = true; +} + +void TerrainSystem::Deactivate() +{ + m_requestedSettings.m_systemActive = false; + m_terrainSettingsDirty = true; +} + +void TerrainSystem::SetWorldMin(AZ::Vector3 worldOrigin) +{ + m_requestedSettings.m_worldBounds.SetMin(worldOrigin); + m_terrainSettingsDirty = true; +} + +void TerrainSystem::SetWorldMax(AZ::Vector3 worldBounds) +{ + m_requestedSettings.m_worldBounds.SetMax(worldBounds); + m_terrainSettingsDirty = true; +} + +void TerrainSystem::SetHeightQueryResolution(AZ::Vector2 queryResolution) +{ + m_requestedSettings.m_heightQueryResolution = queryResolution; + m_terrainSettingsDirty = true; +} + +void TerrainSystem::SetDebugWireframe(bool wireframeEnabled) +{ + m_requestedSettings.m_debugWireframeEnabled = wireframeEnabled; + m_terrainSettingsDirty = true; +} + + +AZ::Aabb TerrainSystem::GetTerrainAabb() const +{ + return m_currentSettings.m_worldBounds; +} + +AZ::Vector2 TerrainSystem::GetTerrainGridResolution() const +{ + return m_currentSettings.m_heightQueryResolution; +} + +float TerrainSystem::GetHeightSynchronous(float x, float y) const +{ + AZ::Vector3 inPosition((float)x, (float)y, m_currentSettings.m_worldBounds.GetMin().GetZ()); + AZ::Vector3 outPosition((float)x, (float)y, m_currentSettings.m_worldBounds.GetMin().GetZ()); + + AZStd::shared_lock lock(m_areaMutex); + + if (!m_registeredAreas.empty()) + { + for (auto& [areaId, areaBounds] : m_registeredAreas) + { + inPosition.SetZ(areaBounds.GetMin().GetZ()); + if (areaBounds.Contains(inPosition)) + { + Terrain::TerrainAreaHeightRequestBus::Event( + areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition, + Terrain::TerrainAreaHeightRequestBus::Events::Sampler::DEFAULT); + } + } + } + + return AZ::GetClamp( + outPosition.GetZ(), m_currentSettings.m_worldBounds.GetMin().GetZ(), m_currentSettings.m_worldBounds.GetMax().GetZ()); +} + +float TerrainSystem::GetHeight(AZ::Vector3 position, [[maybe_unused]] Sampler sampler, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return GetHeightSynchronous(position.GetX(), position.GetY()); +} + +float TerrainSystem::GetHeightFromFloats( + float x, float y, [[maybe_unused]] Sampler sampler, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return GetHeightSynchronous(x, y); +} + +bool TerrainSystem::GetIsHoleFromFloats( + [[maybe_unused]] float x, [[maybe_unused]] float y, [[maybe_unused]] Sampler sampleFilter) const +{ + return false; +} + +AZ::Vector3 TerrainSystem::GetNormalSynchronous([[maybe_unused]] float x, [[maybe_unused]] float y) const +{ + return AZ::Vector3::CreateAxisZ(); +} + +AZ::Vector3 TerrainSystem::GetNormal( + AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return GetNormalSynchronous(position.GetX(), position.GetY()); +} + +AZ::Vector3 TerrainSystem::GetNormalFromFloats( + float x, float y, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return GetNormalSynchronous(x, y); +} + + +AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeight( + [[maybe_unused]] AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return AzFramework::SurfaceData::SurfaceTagWeight(); +} + +AzFramework::SurfaceData::SurfaceTagWeight TerrainSystem::GetMaxSurfaceWeightFromFloats( + [[maybe_unused]] float x, + [[maybe_unused]] float y, + [[maybe_unused]] Sampler sampleFilter, + [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return AzFramework::SurfaceData::SurfaceTagWeight(); +} + +const char* TerrainSystem::GetMaxSurfaceName( + [[maybe_unused]] AZ::Vector3 position, [[maybe_unused]] Sampler sampleFilter, [[maybe_unused]] bool* terrainExistsPtr) const +{ + if (terrainExistsPtr) + { + *terrainExistsPtr = true; + } + + return ""; +} + +/* +void TerrainSystem::GetSurfaceWeights( + [[maybe_unused]] const AZ::Vector3& inPosition, + [[maybe_unused]] Sampler sampleFilter, + [[maybe_unused]] SurfaceData::SurfaceTagWeightMap& outSurfaceWeights) +{ + // TODO: implement +} + +void TerrainSystem::GetSurfacePoint( + const AZ::Vector3& inPosition, [[maybe_unused]] Sampler sampleFilter, SurfaceData::SurfacePoint& outSurfacePoint) +{ + // TODO: Handle sampleFilter + + float sampleX = inPosition.GetX(); + float sampleY = inPosition.GetY(); + + GetHeight(inPosition, sampleFilter, outSurfacePoint.m_position); + //outSurfacePoint.m_position = AZ::Vector3(sampleX, sampleY, GetHeightSynchronous(sampleX, sampleY)); + outSurfacePoint.m_normal = GetNormalSynchronous(sampleX, sampleY); +} + + + + +void TerrainSystem::ProcessHeightsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, Sampler sampleFilter, SurfacePointRegionFillCallback perPositionCallback, TerrainDataReadyCallback onComplete) +{ + // Don't bother processing if we don't have a callback + if (!perPositionCallback) + { + return; + } + + uint32_t numSamplesX = static_cast((inRegion.GetMax().GetX() - inRegion.GetMin().GetX()) / stepSize.GetX()); + uint32_t numSamplesY = static_cast((inRegion.GetMax().GetY() - inRegion.GetMin().GetY()) / stepSize.GetY()); + + for (uint32_t y = 0; y < numSamplesY; y++) + { + for (uint32_t x = 0; x < numSamplesX; x++) + { + float fx = (float)(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + float fy = (float)(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + + SurfaceData::SurfacePoint surfacePoint; + GetHeight(AZ::Vector3(fx, fy, 0.0f), sampleFilter, surfacePoint.m_position); + perPositionCallback(surfacePoint, x, y); + } + } + + if (onComplete) + { + onComplete(); + } +} + + +void TerrainSystem::ProcessSurfacePointsFromRegion(const AZ::Aabb& inRegion, const AZ::Vector2 stepSize, Sampler sampleFilter, SurfacePointRegionFillCallback perPositionCallback, TerrainDataReadyCallback onComplete) +{ + // Don't bother processing if we don't have a callback + if (!perPositionCallback) + { + return; + } + + uint32_t numSamplesX = static_cast((inRegion.GetMax().GetX() - inRegion.GetMin().GetX()) / stepSize.GetX()); + uint32_t numSamplesY = static_cast((inRegion.GetMax().GetY() - inRegion.GetMin().GetY()) / stepSize.GetY()); + + for (uint32_t y = 0; y < numSamplesY; y++) + { + for (uint32_t x = 0; x < numSamplesX; x++) + { + float fx = (float)(inRegion.GetMin().GetX() + (x * stepSize.GetX())); + float fy = (float)(inRegion.GetMin().GetY() + (y * stepSize.GetY())); + + SurfaceData::SurfacePoint surfacePoint; + GetSurfacePoint(AZ::Vector3(fx, fy, inRegion.GetMin().GetZ()), sampleFilter, surfacePoint); + perPositionCallback(surfacePoint, x, y); + } + } + + if (onComplete) + { + onComplete(); + } +} +*/ + +void TerrainSystem::SystemActivate() +{ + { + AZStd::shared_lock lock(m_areaMutex); + m_registeredAreas.clear(); + } + + AzFramework::Terrain::TerrainDataRequestBus::Handler::BusConnect(); + + TerrainAreaRequestBus::Broadcast(&TerrainAreaRequestBus::Events::RegisterArea); +} + +void TerrainSystem::SystemDeactivate() +{ + AzFramework::Terrain::TerrainDataRequestBus::Handler::BusDisconnect(); + + { + AZStd::shared_lock lock(m_areaMutex); + m_registeredAreas.clear(); + } + + const AZ::RPI::Scene* scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene().get(); + auto terrainFeatureProcessor = scene->GetFeatureProcessor(); + if (terrainFeatureProcessor) + { + terrainFeatureProcessor->RemoveTerrainData(); + } +} + +void TerrainSystem::RegisterArea(AZ::EntityId areaId) +{ + { + AZStd::unique_lock lock(m_areaMutex); + AZ::Aabb aabb = AZ::Aabb::CreateNull(); + LmbrCentral::ShapeComponentRequestsBus::EventResult(aabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb); + m_registeredAreas[areaId] = aabb; + } + + RefreshArea(areaId); +} + +void TerrainSystem::UnregisterArea(AZ::EntityId areaId) +{ + { + AZStd::unique_lock lock(m_areaMutex); + AZ::Aabb aabb = AZ::Aabb::CreateNull(); + LmbrCentral::ShapeComponentRequestsBus::EventResult(aabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb); + m_registeredAreas.erase(areaId); + } + + RefreshArea(areaId); +} + +void TerrainSystem::RefreshArea(AZ::EntityId areaId) +{ + AZStd::unique_lock lock(m_areaMutex); + + auto areaAabb = m_registeredAreas.find(areaId); + + AZ::Aabb oldAabb = (areaAabb != m_registeredAreas.end()) ? areaAabb->second : AZ::Aabb::CreateNull(); + AZ::Aabb newAabb = AZ::Aabb::CreateNull(); + LmbrCentral::ShapeComponentRequestsBus::EventResult(newAabb, areaId, &LmbrCentral::ShapeComponentRequestsBus::Events::GetEncompassingAabb); + + m_registeredAreas[areaId] = newAabb; + + AZ::Aabb expandedAabb = oldAabb; + expandedAabb.AddAabb(newAabb); + + m_dirtyRegion.AddAabb(expandedAabb); + m_terrainHeightDirty = true; +} + +void TerrainSystem::OnTick(float /*deltaTime*/, AZ::ScriptTimePoint /*time*/) +{ + bool terrainSettingsChanged = false; + + if (m_terrainSettingsDirty) + { + m_terrainSettingsDirty = false; + + // This needs to happen before the "system active" check below, because activating the system will cause the various + // terrain layer areas to request the current world bounds. + if (m_requestedSettings.m_worldBounds != m_currentSettings.m_worldBounds) + { + m_dirtyRegion = m_currentSettings.m_worldBounds; + m_dirtyRegion.AddAabb(m_requestedSettings.m_worldBounds); + m_terrainHeightDirty = true; + m_currentSettings.m_worldBounds = m_requestedSettings.m_worldBounds; + terrainSettingsChanged = true; + } + + if (m_requestedSettings.m_debugWireframeEnabled != m_currentSettings.m_debugWireframeEnabled) + { + m_dirtyRegion = AZ::Aabb::CreateNull(); + m_terrainHeightDirty = true; + terrainSettingsChanged = true; + } + + if (m_requestedSettings.m_heightQueryResolution != m_currentSettings.m_heightQueryResolution) + { + m_dirtyRegion = AZ::Aabb::CreateNull(); + m_terrainHeightDirty = true; + terrainSettingsChanged = true; + } + + if (m_requestedSettings.m_systemActive != m_currentSettings.m_systemActive) + { + m_requestedSettings.m_systemActive ? SystemActivate() : SystemDeactivate(); + + // Null dirty region will be interpreted as updating everything + m_dirtyRegion = AZ::Aabb::CreateNull(); + m_terrainHeightDirty = true; + terrainSettingsChanged = true; + } + + m_currentSettings = m_requestedSettings; + } + + if (m_currentSettings.m_systemActive && m_terrainHeightDirty) + { + AZStd::shared_lock lock(m_areaMutex); + + AZ::EntityId entityId(0); + AZ::Transform transform = AZ::Transform::CreateTranslation(m_currentSettings.m_worldBounds.GetCenter()); + + uint32_t width = aznumeric_cast( + (float)m_currentSettings.m_worldBounds.GetXExtent() / m_currentSettings.m_heightQueryResolution.GetX()); + uint32_t height = aznumeric_cast( + (float)m_currentSettings.m_worldBounds.GetYExtent() / m_currentSettings.m_heightQueryResolution.GetY()); + AZStd::vector pixels; + pixels.resize(width * height); + const uint32_t pixelDataSize = width * height * sizeof(float); + memset(pixels.data(), 0, pixelDataSize); + + for (auto& [areaId, areaBounds] : m_registeredAreas) + { + for (uint32_t y = 0; y < height; y++) + { + for (uint32_t x = 0; x < width; x++) + { + AZ::Vector3 inPosition( + (x * m_currentSettings.m_heightQueryResolution.GetX()) + m_currentSettings.m_worldBounds.GetMin().GetX(), + (y * m_currentSettings.m_heightQueryResolution.GetY()) + m_currentSettings.m_worldBounds.GetMin().GetY(), + areaBounds.GetMin().GetZ()); + if (areaBounds.Contains(inPosition)) + { + AZ::Vector3 outPosition; + const Terrain::TerrainAreaHeightRequests::Sampler sampleFilter = + Terrain::TerrainAreaHeightRequests::Sampler::DEFAULT; + + Terrain::TerrainAreaHeightRequestBus::Event( + areaId, &Terrain::TerrainAreaHeightRequestBus::Events::GetHeight, inPosition, outPosition, sampleFilter); + + pixels[(y * width) + x] = (outPosition.GetZ() - m_currentSettings.m_worldBounds.GetMin().GetZ()) / + m_currentSettings.m_worldBounds.GetExtents().GetZ(); + } + } + } + } + + const AZ::RPI::Scene* scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene().get(); + auto terrainFeatureProcessor = scene->GetFeatureProcessor(); + + AZ_Assert(terrainFeatureProcessor, "Unable to find a TerrainFeatureProcessor."); + if (terrainFeatureProcessor) + { + terrainFeatureProcessor->UpdateTerrainData( + entityId, transform, m_currentSettings.m_worldBounds, m_currentSettings.m_heightQueryResolution.GetX(), width, height, + pixels); + } + } + + if (terrainSettingsChanged || m_terrainHeightDirty) + { + AzFramework::Terrain::TerrainDataNotifications::TerrainDataChangedMask changeMask = + AzFramework::Terrain::TerrainDataNotifications::TerrainDataChangedMask::None; + + if (terrainSettingsChanged) + { + changeMask = static_cast( + changeMask | AzFramework::Terrain::TerrainDataNotifications::TerrainDataChangedMask::Settings); + } + if (m_terrainHeightDirty) + { + changeMask = static_cast( + changeMask | AzFramework::Terrain::TerrainDataNotifications::TerrainDataChangedMask::HeightData); + } + + // Make sure to set these *before* calling OnTerrainDataChanged, since it's possible that subsystems reacting to that call will + // cause the data to become dirty again. + AZ::Aabb dirtyRegion = m_dirtyRegion; + m_terrainHeightDirty = false; + m_dirtyRegion = AZ::Aabb::CreateNull(); + + AzFramework::Terrain::TerrainDataNotificationBus::Broadcast( + &AzFramework::Terrain::TerrainDataNotificationBus::Events::OnTerrainDataChanged, dirtyRegion, + changeMask); + } + +} diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h new file mode 100644 index 0000000000..56ed182047 --- /dev/null +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystem.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace Terrain +{ + class TerrainSystem + : public AzFramework::Terrain::TerrainDataRequestBus::Handler + , private Terrain::TerrainSystemServiceRequestBus::Handler + , private AZ::TickBus::Handler + { + public: + TerrainSystem(); + ~TerrainSystem(); + + /////////////////////////////////////////// + // TerrainSystemServiceRequestBus::Handler Impl + + void SetWorldMin(AZ::Vector3 worldOrigin) override; + void SetWorldMax(AZ::Vector3 worldBounds) override; + void SetHeightQueryResolution(AZ::Vector2 queryResolution) override; + void SetDebugWireframe(bool wireframeEnabled) override; + + void Activate() override; + void Deactivate() override; + + void RegisterArea(AZ::EntityId areaId) override; + void UnregisterArea(AZ::EntityId areaId) override; + void RefreshArea(AZ::EntityId areaId) override; + + /////////////////////////////////////////// + // TerrainDataRequestBus::Handler Impl + AZ::Vector2 GetTerrainGridResolution() const override; + AZ::Aabb GetTerrainAabb() const override; + + //! Returns terrains height in meters at location x,y. + //! @terrainExistsPtr: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain + //! HOLE then *terrainExistsPtr will become false, + //! otherwise *terrainExistsPtr will become true. + float GetHeight(AZ::Vector3 position, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + float GetHeightFromFloats(float x, float y, Sampler sampler = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + + //! Given an XY coordinate, return the max surface type and weight. + //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain + //! HOLE then *terrainExistsPtr will be set to false, + //! otherwise *terrainExistsPtr will be set to true. + AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeight( + AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + AzFramework::SurfaceData::SurfaceTagWeight GetMaxSurfaceWeightFromFloats( + float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + + //! Convenience function for low level systems that can't do a reverse lookup from Crc to string. Everyone else should use + //! GetMaxSurfaceWeight or GetMaxSurfaceWeightFromFloats. Not available in the behavior context. Returns nullptr if the position is + //! inside a hole or outside of the terrain boundaries. + const char* GetMaxSurfaceName( + AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + + //! Returns true if there's a hole at location x,y. + //! Also returns true if there's no terrain data at location x,y. + bool GetIsHoleFromFloats(float x, float y, Sampler sampleFilter = Sampler::BILINEAR) const override; + + // Given an XY coordinate, return the surface normal. + //! @terrainExists: Can be nullptr. If != nullptr then, if there's no terrain at location x,y or location x,y is inside a terrain + //! HOLE then *terrainExistsPtr will be set to false, + //! otherwise *terrainExistsPtr will be set to true. + AZ::Vector3 GetNormal( + AZ::Vector3 position, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + AZ::Vector3 GetNormalFromFloats( + float x, float y, Sampler sampleFilter = Sampler::BILINEAR, bool* terrainExistsPtr = nullptr) const override; + + private: + float GetHeightSynchronous(float x, float y) const; + AZ::Vector3 GetNormalSynchronous(float x, float y) const; + + // AZ::TickBus::Handler overrides ... + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override; + + void SystemActivate(); + void SystemDeactivate(); + + struct TerrainSystemSettings + { + AZ::Aabb m_worldBounds; + AZ::Vector2 m_heightQueryResolution{ 1.0f }; + bool m_debugWireframeEnabled{ false }; + bool m_systemActive{ false }; + }; + + TerrainSystemSettings m_currentSettings; + TerrainSystemSettings m_requestedSettings; + + bool m_terrainSettingsDirty = true; + bool m_terrainHeightDirty = false; + AZ::Aabb m_dirtyRegion; + + mutable AZStd::shared_mutex m_areaMutex; + AZStd::unordered_map m_registeredAreas; + }; +} // namespace Terrain diff --git a/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h new file mode 100644 index 0000000000..08521fd780 --- /dev/null +++ b/Gems/Terrain/Code/Source/TerrainSystem/TerrainSystemBus.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace Terrain +{ + /** + * A bus to signal the life times of terrain areas + * Note: all the API are meant to be queued events + */ + class TerrainSystemServiceRequests + : public AZ::EBusTraits + { + public: + //////////////////////////////////////////////////////////////////////// + // EBusTraits + // singleton pattern + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; + using MutexType = AZStd::recursive_mutex; + //////////////////////////////////////////////////////////////////////// + + virtual ~TerrainSystemServiceRequests() = default; + + virtual void Activate() = 0; + virtual void Deactivate() = 0; + + virtual void SetWorldMin(AZ::Vector3 worldOrigin) = 0; + virtual void SetWorldMax(AZ::Vector3 worldBounds) = 0; + virtual void SetHeightQueryResolution(AZ::Vector2 queryResolution) = 0; + virtual void SetDebugWireframe(bool wireframeEnabled) = 0; + + // register an area to override terrain + virtual void RegisterArea(AZ::EntityId areaId) = 0; + virtual void UnregisterArea(AZ::EntityId areaId) = 0; + virtual void RefreshArea(AZ::EntityId areaId) = 0; + }; + + using TerrainSystemServiceRequestBus = AZ::EBus; + + /** + * A bus to signal the life times of terrain areas + * Note: all the API are meant to be queued events + */ + class TerrainAreaRequests + : public AZ::ComponentBus + { + public: + //////////////////////////////////////////////////////////////////////// + // EBusTraits + using MutexType = AZStd::recursive_mutex; + //////////////////////////////////////////////////////////////////////// + + virtual ~TerrainAreaRequests() = default; + + virtual void RegisterArea() = 0; + virtual void RefreshArea() = 0; + + }; + + using TerrainAreaRequestBus = AZ::EBus; + + /** + * A bus to signal the life times of terrain areas + * Note: all the API are meant to be queued events + */ + class TerrainAreaHeightRequests + : public AZ::ComponentBus + { + public: + //////////////////////////////////////////////////////////////////////// + // EBusTraits + using MutexType = AZStd::recursive_mutex; + //////////////////////////////////////////////////////////////////////// + + virtual ~TerrainAreaHeightRequests() = default; + + enum class Sampler + { + BILINEAR, // Get the value at the requested location, using terrain sample grid to bilinear filter between sample grid points + CLAMP, // Clamp the input point to the terrain sample grid, then get the exact value + EXACT, // Directly get the value at the location, regardless of terrain sample grid density + + DEFAULT = BILINEAR + }; + + enum SurfacePointDataMask + { + POSITION = 0x01, + NORMAL = 0x02, + SURFACE_WEIGHTS = 0x04, + + DEFAULT = POSITION | NORMAL | SURFACE_WEIGHTS + }; + + // Synchronous single input location. The Vector3 input position versions are defined to ignore the input Z value. + + virtual void GetHeight(const AZ::Vector3& inPosition, AZ::Vector3& outPosition, Sampler sampleFilter = Sampler::DEFAULT) = 0; + virtual void GetNormal(const AZ::Vector3& inPosition, AZ::Vector3& outNormal, Sampler sampleFilter = Sampler::DEFAULT) = 0; + //virtual void GetSurfaceWeights(const AZ::Vector3& inPosition, SurfaceTagWeightMap& outSurfaceWeights, Sampler sampleFilter = DEFAULT) = 0; + //virtual void GetSurfacePoint(const AZ::Vector3& inPosition, SurfacePoint& outSurfacePoint, SurfacePointDataMask dataMask = DEFAULT, Sampler sampleFilter = DEFAULT) = 0; + }; + + using TerrainAreaHeightRequestBus = AZ::EBus; + +} diff --git a/Gems/Terrain/Code/terrain_editor_shared_files.cmake b/Gems/Terrain/Code/terrain_editor_shared_files.cmake index 68ec9aeb54..9868f7d310 100644 --- a/Gems/Terrain/Code/terrain_editor_shared_files.cmake +++ b/Gems/Terrain/Code/terrain_editor_shared_files.cmake @@ -7,6 +7,14 @@ # set(FILES + Source/EditorComponents/EditorTerrainHeightGradientListComponent.cpp + Source/EditorComponents/EditorTerrainHeightGradientListComponent.h + Source/EditorComponents/EditorTerrainLayerSpawnerComponent.cpp + Source/EditorComponents/EditorTerrainLayerSpawnerComponent.h + Source/EditorComponents/EditorTerrainWorldComponent.cpp + Source/EditorComponents/EditorTerrainWorldComponent.h + Source/EditorComponents/EditorTerrainWorldDebuggerComponent.cpp + Source/EditorComponents/EditorTerrainWorldDebuggerComponent.h Source/EditorComponents/EditorTerrainSystemComponent.cpp Source/EditorComponents/EditorTerrainSystemComponent.h Source/EditorTerrainModule.cpp diff --git a/Gems/Terrain/Code/terrain_files.cmake b/Gems/Terrain/Code/terrain_files.cmake index c67d0c63b4..6a76dd7141 100644 --- a/Gems/Terrain/Code/terrain_files.cmake +++ b/Gems/Terrain/Code/terrain_files.cmake @@ -7,8 +7,21 @@ # set(FILES + Source/Components/TerrainHeightGradientListComponent.cpp + Source/Components/TerrainHeightGradientListComponent.h + Source/Components/TerrainLayerSpawnerComponent.cpp + Source/Components/TerrainLayerSpawnerComponent.h Source/Components/TerrainSurfaceDataSystemComponent.cpp Source/Components/TerrainSurfaceDataSystemComponent.h Source/Components/TerrainSystemComponent.cpp Source/Components/TerrainSystemComponent.h + Source/Components/TerrainWorldComponent.cpp + Source/Components/TerrainWorldComponent.h + Source/Components/TerrainWorldDebuggerComponent.cpp + Source/Components/TerrainWorldDebuggerComponent.h + Source/TerrainRenderer/TerrainFeatureProcessor.cpp + Source/TerrainRenderer/TerrainFeatureProcessor.h + Source/TerrainSystem/TerrainSystem.cpp + Source/TerrainSystem/TerrainSystem.h + Source/TerrainSystem/TerrainSystemBus.h ) From 426ba2f4a6ade94c0dc1a4c97b82fc96e81cbe08 Mon Sep 17 00:00:00 2001 From: AMZN-AlexOteiza <82234181+AMZN-AlexOteiza@users.noreply.github.com> Date: Tue, 24 Aug 2021 20:54:48 +0200 Subject: [PATCH 26/27] Added conversion of physics tests using new optimizations. Fixed issue on editor test framework to close the AP correctly (#3145) * Commit Signed-off-by: Garcia Ruiz * Removed xfail Signed-off-by: Garcia Ruiz * Fix for ap not closing for optimized tests Signed-off-by: Garcia Ruiz * renamed tests to _Optimized Signed-off-by: Garcia Ruiz * Added xfail so the test will run in jenkins without affecting outcomes Signed-off-by: Garcia Ruiz Co-authored-by: Garcia Ruiz --- .../Gem/PythonTests/physics/CMakeLists.txt | 13 + .../physics/TestSuite_Main_Optimized.py | 349 ++++++++++++++++++ .../physics/TestSuite_Main_Test.py | 105 ------ .../_internal/pytest_plugin/editor_test.py | 2 +- .../ly_test_tools/o3de/editor_test.py | 112 +++--- 5 files changed, 418 insertions(+), 163 deletions(-) create mode 100644 AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Optimized.py delete mode 100644 AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Test.py diff --git a/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt index eb37db1943..2557faee43 100644 --- a/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt +++ b/AutomatedTesting/Gem/PythonTests/physics/CMakeLists.txt @@ -19,6 +19,19 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS) COMPONENT Physics ) + ly_add_pytest( + NAME AutomatedTesting::PhysicsTests_Main_Optimized + TEST_SUITE main + TEST_SERIAL + PATH ${CMAKE_CURRENT_LIST_DIR}/TestSuite_Main_Optimized.py + TIMEOUT 1500 + RUNTIME_DEPENDENCIES + Legacy::Editor + AZ::AssetProcessor + AutomatedTesting.Assets + COMPONENT + Physics + ) ly_add_pytest( NAME AutomatedTesting::PhysicsTests_Periodic TEST_SUITE periodic diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Optimized.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Optimized.py new file mode 100644 index 0000000000..75e226fba1 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Optimized.py @@ -0,0 +1,349 @@ +""" +Copyright (c) Contributors to the Open 3D Engine Project. +For complete copyright and license terms please see the LICENSE at the root of this distribution. + +SPDX-License-Identifier: Apache-2.0 OR MIT +""" + +import pytest +import os +import sys +import inspect + +from ly_test_tools import LAUNCHERS +from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite +from .FileManagement import FileManagement as fm + +# Custom test spec, it provides functionality to override files +class EditorSingleTest_WithFileOverrides(EditorSingleTest): + # Specify here what files to override, [(original, override), ...] + files_to_override = [()] + # Base directory of the files (Default path is {ProjectName}) + base_dir = None + # True will will search sub-directories for the files in base + search_subdirs = False + + @classmethod + def wrap_run(cls, instance, request, workspace, editor, editor_test_results, launcher_platform): + root_path = cls.base_dir + if root_path is not None: + root_path = os.path.join(workspace.paths.engine_root(), root_path) + else: + # Default to project folder + root_path = workspace.paths.project() + + # Try to locate both target and source files + original_file_list, override_file_list = zip(*cls.files_to_override) + try: + file_list = fm._find_files(original_file_list + override_file_list, root_path, cls.search_subdirs) + except RuntimeWarning as w: + assert False, ( + w.message + + " Please check use of search_subdirs; make sure you are using the correct parent directory." + ) + + for f in original_file_list: + fm._restore_file(f, file_list[f]) + fm._backup_file(f, file_list[f]) + + for original, override in cls.files_to_override: + fm._copy_file(override, file_list[override], original, file_list[override]) + + yield # Run Test + for f in original_file_list: + fm._restore_file(f, file_list[f]) + + +@pytest.mark.xfail(reason="Optimized tests are experimental, we will enable xfail and monitor them temporarly.") +@pytest.mark.SUITE_main +@pytest.mark.parametrize("launcher_platform", ['windows_editor']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +class TestAutomation(EditorTestSuite): + + @staticmethod + def get_number_parallel_editors(): + return 16 + + ######################################### + # Non-atomic tests: These need to be run in a single editor because they have custom setup and teardown + class C4044459_Material_DynamicFriction(EditorSingleTest_WithFileOverrides): + from . import C4044459_Material_DynamicFriction as test_module + files_to_override = [ + ('physxsystemconfiguration.setreg', 'C4044459_Material_DynamicFriction.setreg_override') + ] + base_dir = "AutomatedTesting/Registry" + + class C4982593_PhysXCollider_CollisionLayerTest(EditorSingleTest_WithFileOverrides): + from . import C4982593_PhysXCollider_CollisionLayerTest as test_module + files_to_override = [ + ('physxsystemconfiguration.setreg', 'C4982593_PhysXCollider_CollisionLayer.setreg_override') + ] + base_dir = "AutomatedTesting/Registry" + ######################################### + + class C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC(EditorSharedTest): + from . import C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module + + class C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies(EditorSharedTest): + from . import C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies as test_module + + class C15425929_Undo_Redo(EditorSharedTest): + from . import C15425929_Undo_Redo as test_module + + class C4976243_Collision_SameCollisionGroupDiffCollisionLayers(EditorSharedTest): + from . import C4976243_Collision_SameCollisionGroupDiffCollisionLayers as test_module + + class C14654881_CharacterController_SwitchLevels(EditorSharedTest): + from . import C14654881_CharacterController_SwitchLevels as test_module + + class C17411467_AddPhysxRagdollComponent(EditorSharedTest): + from . import C17411467_AddPhysxRagdollComponent as test_module + + class C12712453_ScriptCanvas_MultipleRaycastNode(EditorSharedTest): + from . import C12712453_ScriptCanvas_MultipleRaycastNode as test_module + + class C18243586_Joints_HingeLeadFollowerCollide(EditorSharedTest): + from . import C18243586_Joints_HingeLeadFollowerCollide as test_module + + class C4982803_Enable_PxMesh_Option(EditorSharedTest): + from . import C4982803_Enable_PxMesh_Option as test_module + + class C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain(EditorSharedTest): + from . import C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain as test_module + + class C3510642_Terrain_NotCollideWithTerrain(EditorSharedTest): + from . import C3510642_Terrain_NotCollideWithTerrain as test_module + + class C4976195_RigidBodies_InitialLinearVelocity(EditorSharedTest): + from . import C4976195_RigidBodies_InitialLinearVelocity as test_module + + class C4976206_RigidBodies_GravityEnabledActive(EditorSharedTest): + from . import C4976206_RigidBodies_GravityEnabledActive as test_module + + class C4976207_PhysXRigidBodies_KinematicBehavior(EditorSharedTest): + from . import C4976207_PhysXRigidBodies_KinematicBehavior as test_module + + class C5932042_PhysXForceRegion_LinearDamping(EditorSharedTest): + from . import C5932042_PhysXForceRegion_LinearDamping as test_module + + class C5932043_ForceRegion_SimpleDragOnRigidBodies(EditorSharedTest): + from . import C5932043_ForceRegion_SimpleDragOnRigidBodies as test_module + + class C5959760_PhysXForceRegion_PointForceExertion(EditorSharedTest): + from . import C5959760_PhysXForceRegion_PointForceExertion as test_module + + class C5959764_ForceRegion_ForceRegionImpulsesCapsule(EditorSharedTest): + from . import C5959764_ForceRegion_ForceRegionImpulsesCapsule as test_module + + class C5340400_RigidBody_ManualMomentOfInertia(EditorSharedTest): + from . import C5340400_RigidBody_ManualMomentOfInertia as test_module + + class C4976210_COM_ManualSetting(EditorSharedTest): + from . import C4976210_COM_ManualSetting as test_module + + class C4976194_RigidBody_PhysXComponentIsValid(EditorSharedTest): + from . import C4976194_RigidBody_PhysXComponentIsValid as test_module + + class C5932045_ForceRegion_Spline(EditorSharedTest): + from . import C5932045_ForceRegion_Spline as test_module + + class C4982797_Collider_ColliderOffset(EditorSharedTest): + from . import C4982797_Collider_ColliderOffset as test_module + + class C4976200_RigidBody_AngularDampingObjectRotation(EditorSharedTest): + from . import C4976200_RigidBody_AngularDampingObjectRotation as test_module + + class C5689529_Verify_Terrain_RigidBody_Collider_Mesh(EditorSharedTest): + from . import C5689529_Verify_Terrain_RigidBody_Collider_Mesh as test_module + + class C5959810_ForceRegion_ForceRegionCombinesForces(EditorSharedTest): + from . import C5959810_ForceRegion_ForceRegionCombinesForces as test_module + + class C5959765_ForceRegion_AssetGetsImpulsed(EditorSharedTest): + from . import C5959765_ForceRegion_AssetGetsImpulsed as test_module + + class C6274125_ScriptCanvas_TriggerEvents(EditorSharedTest): + from . import C6274125_ScriptCanvas_TriggerEvents as test_module + # needs to be updated to log for unexpected lines + # expected_lines = test_module.LogLines.expected_lines + + class C6090554_ForceRegion_PointForceNegative(EditorSharedTest): + from . import C6090554_ForceRegion_PointForceNegative as test_module + + class C6090550_ForceRegion_WorldSpaceForceNegative(EditorSharedTest): + from . import C6090550_ForceRegion_WorldSpaceForceNegative as test_module + + class C6090552_ForceRegion_LinearDampingNegative(EditorSharedTest): + from . import C6090552_ForceRegion_LinearDampingNegative as test_module + + class C5968760_ForceRegion_CheckNetForceChange(EditorSharedTest): + from . import C5968760_ForceRegion_CheckNetForceChange as test_module + + class C12712452_ScriptCanvas_CollisionEvents(EditorSharedTest): + from . import C12712452_ScriptCanvas_CollisionEvents as test_module + + class C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude(EditorSharedTest): + from . import C12868578_ForceRegion_DirectionHasNoAffectOnMagnitude as test_module + + class C4976204_Verify_Start_Asleep_Condition(EditorSharedTest): + from . import C4976204_Verify_Start_Asleep_Condition as test_module + + class C6090546_ForceRegion_SliceFileInstantiates(EditorSharedTest): + from . import C6090546_ForceRegion_SliceFileInstantiates as test_module + + class C6090551_ForceRegion_LocalSpaceForceNegative(EditorSharedTest): + from . import C6090551_ForceRegion_LocalSpaceForceNegative as test_module + + class C6090553_ForceRegion_SimpleDragForceOnRigidBodies(EditorSharedTest): + from . import C6090553_ForceRegion_SimpleDragForceOnRigidBodies as test_module + + class C4976209_RigidBody_ComputesCOM(EditorSharedTest): + from . import C4976209_RigidBody_ComputesCOM as test_module + + class C4976201_RigidBody_MassIsAssigned(EditorSharedTest): + from . import C4976201_RigidBody_MassIsAssigned as test_module + + class C12868580_ForceRegion_SplineModifiedTransform(EditorSharedTest): + from . import C12868580_ForceRegion_SplineModifiedTransform as test_module + + class C12712455_ScriptCanvas_ShapeCastVerification(EditorSharedTest): + from . import C12712455_ScriptCanvas_ShapeCastVerification as test_module + + class C4976197_RigidBodies_InitialAngularVelocity(EditorSharedTest): + from . import C4976197_RigidBodies_InitialAngularVelocity as test_module + + class C6090555_ForceRegion_SplineFollowOnRigidBodies(EditorSharedTest): + from . import C6090555_ForceRegion_SplineFollowOnRigidBodies as test_module + + class C6131473_StaticSlice_OnDynamicSliceSpawn(EditorSharedTest): + from . import C6131473_StaticSlice_OnDynamicSliceSpawn as test_module + + class C5959808_ForceRegion_PositionOffset(EditorSharedTest): + from . import C5959808_ForceRegion_PositionOffset as test_module + + @pytest.mark.xfail(reason="Something with the CryRenderer disabling is causing this test to fail now.") + class C13895144_Ragdoll_ChangeLevel(EditorSharedTest): + from . import C13895144_Ragdoll_ChangeLevel as test_module + + class C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody(EditorSharedTest): + from . import C5968759_ForceRegion_ExertsSeveralForcesOnRigidBody as test_module + + @pytest.mark.xfail(reason="This test will sometimes fail as the ball will continue to roll before the timeout is reached.") + class C4976202_RigidBody_StopsWhenBelowKineticThreshold(EditorSharedTest): + from . import C4976202_RigidBody_StopsWhenBelowKineticThreshold as test_module + + class C13351703_COM_NotIncludeTriggerShapes(EditorSharedTest): + from . import C13351703_COM_NotIncludeTriggerShapes as test_module + + class C5296614_PhysXMaterial_ColliderShape(EditorSharedTest): + from . import C5296614_PhysXMaterial_ColliderShape as test_module + + class C4982595_Collider_TriggerDisablesCollision(EditorSharedTest): + from . import C4982595_Collider_TriggerDisablesCollision as test_module + + class C14976307_Gravity_SetGravityWorks(EditorSharedTest): + from . import C14976307_Gravity_SetGravityWorks as test_module + + class C4044694_Material_EmptyLibraryUsesDefault(EditorSharedTest): + from . import C4044694_Material_EmptyLibraryUsesDefault as test_module + + class C15845879_ForceRegion_HighLinearDampingForce(EditorSharedTest): + from . import C15845879_ForceRegion_HighLinearDampingForce as test_module + + class C4976218_RigidBodies_InertiaObjectsNotComputed(EditorSharedTest): + from . import C4976218_RigidBodies_InertiaObjectsNotComputed as test_module + + class C14902098_ScriptCanvas_PostPhysicsUpdate(EditorSharedTest): + from . import C14902098_ScriptCanvas_PostPhysicsUpdate as test_module + # Note: Test needs to be updated to log for unexpected lines + # unexpected_lines = ["Assert"] + test_module.Lines.unexpected + + class C5959761_ForceRegion_PhysAssetExertsPointForce(EditorSharedTest): + from . import C5959761_ForceRegion_PhysAssetExertsPointForce as test_module + + # Marking the Test as expected to fail using the xfail decorator due to sporadic failure on Automated Review: SPEC-3146 + # The test still runs, but a failure of the test doesn't result in the test run failing + @pytest.mark.xfail(reason="Test Sporadically fails with message [ NOT FOUND ] Success: Bar1 : Expected angular velocity") + class C13352089_RigidBodies_MaxAngularVelocity(EditorSharedTest): + from . import C13352089_RigidBodies_MaxAngularVelocity as test_module + + class C18243584_Joints_HingeSoftLimitsConstrained(EditorSharedTest): + from . import C18243584_Joints_HingeSoftLimitsConstrained as test_module + + class C18243589_Joints_BallSoftLimitsConstrained(EditorSharedTest): + from . import C18243589_Joints_BallSoftLimitsConstrained as test_module + + class C18243591_Joints_BallLeadFollowerCollide(EditorSharedTest): + from . import C18243591_Joints_BallLeadFollowerCollide as test_module + + class C19578018_ShapeColliderWithNoShapeComponent(EditorSharedTest): + from . import C19578018_ShapeColliderWithNoShapeComponent as test_module + + class C14861500_DefaultSetting_ColliderShape(EditorSharedTest): + from . import C14861500_DefaultSetting_ColliderShape as test_module + + class C19723164_ShapeCollider_WontCrashEditor(EditorSharedTest): + from . import C19723164_ShapeColliders_WontCrashEditor as test_module + + class C4982800_PhysXColliderShape_CanBeSelected(EditorSharedTest): + from . import C4982800_PhysXColliderShape_CanBeSelected as test_module + + class C4982801_PhysXColliderShape_CanBeSelected(EditorSharedTest): + from . import C4982801_PhysXColliderShape_CanBeSelected as test_module + + class C4982802_PhysXColliderShape_CanBeSelected(EditorSharedTest): + from . import C4982802_PhysXColliderShape_CanBeSelected as test_module + + class C12905528_ForceRegion_WithNonTriggerCollider(EditorSharedTest): + from . import C12905528_ForceRegion_WithNonTriggerCollider as test_module + # Fixme: expected_lines = ["[Warning] (PhysX Force Region) - Please ensure collider component marked as trigger exists in entity"] + + class C5932040_ForceRegion_CubeExertsWorldForce(EditorSharedTest): + from . import C5932040_ForceRegion_CubeExertsWorldForce as test_module + + class C5932044_ForceRegion_PointForceOnRigidBody(EditorSharedTest): + from . import C5932044_ForceRegion_PointForceOnRigidBody as test_module + + class C5959759_RigidBody_ForceRegionSpherePointForce(EditorSharedTest): + from . import C5959759_RigidBody_ForceRegionSpherePointForce as test_module + + class C5959809_ForceRegion_RotationalOffset(EditorSharedTest): + from . import C5959809_ForceRegion_RotationalOffset as test_module + + class C15096740_Material_LibraryUpdatedCorrectly(EditorSharedTest): + from . import C15096740_Material_LibraryUpdatedCorrectly as test_module + + class C4976236_AddPhysxColliderComponent(EditorSharedTest): + from . import C4976236_AddPhysxColliderComponent as test_module + + + @pytest.mark.xfail(reason="This will fail due to this issue ATOM-15487.") + class C14861502_PhysXCollider_AssetAutoAssigned(EditorSharedTest): + from . import C14861502_PhysXCollider_AssetAutoAssigned as test_module + + class C14861501_PhysXCollider_RenderMeshAutoAssigned(EditorSharedTest): + from . import C14861501_PhysXCollider_RenderMeshAutoAssigned as test_module + + class C4044695_PhysXCollider_AddMultipleSurfaceFbx(EditorSharedTest): + from . import C4044695_PhysXCollider_AddMultipleSurfaceFbx as test_module + + class C14861504_RenderMeshAsset_WithNoPxAsset(EditorSharedTest): + from . import C14861504_RenderMeshAsset_WithNoPxAsset as test_module + + class C100000_RigidBody_EnablingGravityWorksPoC(EditorSharedTest): + from . import C100000_RigidBody_EnablingGravityWorksPoC as test_module + + class C4982798_Collider_ColliderRotationOffset(EditorSharedTest): + from . import C4982798_Collider_ColliderRotationOffset as test_module + + class C15308217_NoCrash_LevelSwitch(EditorSharedTest): + from . import C15308217_NoCrash_LevelSwitch as test_module + + class C6090547_ForceRegion_ParentChildForceRegions(EditorSharedTest): + from . import C6090547_ForceRegion_ParentChildForceRegions as test_module + + class C19578021_ShapeCollider_CanBeAdded(EditorSharedTest): + from . import C19578021_ShapeCollider_CanBeAdded as test_module + + class C15425929_Undo_Redo(EditorSharedTest): + from . import C15425929_Undo_Redo as test_module diff --git a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Test.py b/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Test.py deleted file mode 100644 index 6b940f93d1..0000000000 --- a/AutomatedTesting/Gem/PythonTests/physics/TestSuite_Main_Test.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -Copyright (c) Contributors to the Open 3D Engine Project. -For complete copyright and license terms please see the LICENSE at the root of this distribution. - -SPDX-License-Identifier: Apache-2.0 OR MIT -""" - -import pytest -import os -import sys -import inspect - -from ly_test_tools import LAUNCHERS -from ly_test_tools.o3de.editor_test import EditorSingleTest, EditorSharedTest, EditorParallelTest, EditorTestSuite -from .FileManagement import FileManagement as fm - -# Custom test spec, it provides functionality to override files -class EditorSingleTest_WithFileOverrides(EditorSingleTest): - # Specify here what files to override, [(original, override), ...] - files_to_override = [()] - # Base directory of the files (Default path is {ProjectName}) - base_dir = None - # True will will search sub-directories for the files in base - search_subdirs = False - - @classmethod - def wrap_run(cls, instance, request, workspace, editor, editor_test_results, launcher_platform): - root_path = cls.base_dir - if root_path is not None: - root_path = os.path.join(workspace.paths.engine_root(), root_path) - else: - # Default to project folder - root_path = workspace.paths.project() - - # Try to locate both target and source files - original_file_list, override_file_list = zip(*cls.files_to_override) - try: - file_list = fm._find_files(original_file_list + override_file_list, root_path, cls.search_subdirs) - except RuntimeWarning as w: - assert False, ( - w.message - + " Please check use of search_subdirs; make sure you are using the correct parent directory." - ) - - for f in original_file_list: - fm._restore_file(f, file_list[f]) - fm._backup_file(f, file_list[f]) - - for original, override in cls.files_to_override: - fm._copy_file(override, file_list[override], original, file_list[override]) - - yield # Run Test - for f in original_file_list: - fm._restore_file(f, file_list[f]) - - -@pytest.mark.SUITE_main -@pytest.mark.parametrize("launcher_platform", ['windows_editor']) -@pytest.mark.parametrize("project", ["AutomatedTesting"]) -class TestAutomation(EditorTestSuite): - - class C4044459_Material_DynamicFriction(EditorSingleTest_WithFileOverrides): - from . import C4044459_Material_DynamicFriction as test_module - files_to_override = [ - ('physxsystemconfiguration.setreg', 'C4044459_Material_DynamicFriction.setreg_override') - ] - base_dir = "AutomatedTesting/Registry" - - class C4982593_PhysXCollider_CollisionLayerTest(EditorSingleTest_WithFileOverrides): - from . import C4982593_PhysXCollider_CollisionLayerTest as test_module - files_to_override = [ - ('physxsystemconfiguration.setreg', 'C4982593_PhysXCollider_CollisionLayer.setreg_override') - ] - base_dir = "AutomatedTesting/Registry" - - class C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC(EditorSharedTest): - from . import C111111_RigidBody_EnablingGravityWorksUsingNotificationsPoC as test_module - - class C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies(EditorSharedTest): - from . import C5932041_PhysXForceRegion_LocalSpaceForceOnRigidBodies as test_module - - class C15425929_Undo_Redo(EditorSharedTest): - from . import C15425929_Undo_Redo as test_module - - class C4976243_Collision_SameCollisionGroupDiffCollisionLayers(EditorSharedTest): - from . import C4976243_Collision_SameCollisionGroupDiffCollisionLayers as test_module - - class C14654881_CharacterController_SwitchLevels(EditorSharedTest): - from . import C14654881_CharacterController_SwitchLevels as test_module - - class C17411467_AddPhysxRagdollComponent(EditorSharedTest): - from . import C17411467_AddPhysxRagdollComponent as test_module - - class C12712453_ScriptCanvas_MultipleRaycastNode(EditorSharedTest): - from . import C12712453_ScriptCanvas_MultipleRaycastNode as test_module - - class C18243586_Joints_HingeLeadFollowerCollide(EditorSharedTest): - from . import C18243586_Joints_HingeLeadFollowerCollide as test_module - - class C4982803_Enable_PxMesh_Option(EditorSharedTest): - from . import C4982803_Enable_PxMesh_Option as test_module - - class C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain(EditorSharedTest): - from . import C24308873_CylinderShapeCollider_CollidesWithPhysXTerrain as test_module - diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/editor_test.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/editor_test.py index 7c60dd20d2..80a562977b 100644 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/editor_test.py @@ -17,7 +17,7 @@ __test__ = False def pytest_addoption(parser): parser.addoption("--no-editor-batch", action="store_true", help="Don't batch multiple tests in single editor") parser.addoption("--no-editor-parallel", action="store_true", help="Don't run multiple editors in parallel") - parser.addoption("--parallel-editors", type=int, action="store", help="Override the number editors to run at the same time") + parser.addoption("--editors-parallel", type=int, action="store", help="Override the number editors to run at the same time") # Create a custom custom item collection if the class defines pytest_custom_makeitem function # This is used for automtically generating test functions with a custom collector diff --git a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py index 0851c63681..0f456cee1a 100644 --- a/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py +++ b/Tools/LyTestTools/ly_test_tools/o3de/editor_test.py @@ -246,14 +246,24 @@ class EditorTestSuite(): ## Internal ## _TIMEOUT_CRASH_LOG = 20 # Maximum time (seconds) for waiting for a crash file, in secondss - _TEST_FAIL_RETCODE = 0xF # Return code for test failure - _asset_processor = None - _results = {} + _TEST_FAIL_RETCODE = 0xF # Return code for test failure @pytest.fixture(scope="class") - def editor_test_results(self, request): - results = {} - return results + def editor_test_data(self, request): + class TestData(): + def __init__(self): + self.results = {} + self.asset_processor = None + + test_data = TestData() + yield test_data + if test_data.asset_processor: + test_data.asset_processor.stop(1) + test_data.asset_processor.teardown() + test_data.asset_processor = None + editor_utils.kill_all_ly_processes(include_asset_processor=True) + else: + editor_utils.kill_all_ly_processes(include_asset_processor=False) class Runner(): def __init__(self, name, func, tests): @@ -315,26 +325,25 @@ class EditorTestSuite(): name = test_spec.__name__ def make_test_func(name, test_spec): @set_marks({"run_type" : "run_single"}) - def single_run(self, request, workspace, editor, editor_test_results, launcher_platform): + def single_run(self, request, workspace, editor, editor_test_data, launcher_platform): # only single tests are allowed to have setup/teardown, however we can have shared tests that # were explicitly set as single, for example via cmdline argument override is_single_test = issubclass(test_spec, EditorSingleTest) if is_single_test: # Setup step for wrap_run - wrap = test_spec.wrap_run(self, request, workspace, editor, editor_test_results, launcher_platform) + wrap = test_spec.wrap_run(self, request, workspace, editor, editor_test_data, launcher_platform) assert isinstance(wrap, types.GeneratorType), "wrap_run must return a generator, did you forget 'yield'?" next(wrap, None) # Setup step - test_spec.setup(self, request, workspace, editor, editor_test_results, launcher_platform) + test_spec.setup(self, request, workspace, editor, editor_test_data, launcher_platform) # Run - self._run_single_test(request, workspace, editor, editor_test_results, test_spec) + self._run_single_test(request, workspace, editor, editor_test_data, test_spec) if is_single_test: # Teardown - test_spec.teardown(self, request, workspace, editor, editor_test_results, launcher_platform) + test_spec.teardown(self, request, workspace, editor, editor_test_data, launcher_platform) # Teardown step for wrap_run next(wrap, None) return single_run - setattr(self.obj, name, make_test_func(name, test_spec)) f = make_test_func(name, test_spec) if hasattr(test_spec, "pytestmark"): f.pytestmark = test_spec.pytestmark @@ -348,8 +357,8 @@ class EditorTestSuite(): runner = EditorTestSuite.Runner(name, function, tests) def make_func(): @set_marks({"runner" : runner, "run_type" : "run_shared"}) - def shared_run(self, request, workspace, editor, editor_test_results, launcher_platform): - getattr(self, function.__name__)(request, workspace, editor, editor_test_results, runner.tests) + def shared_run(self, request, workspace, editor, editor_test_data, launcher_platform): + getattr(self, function.__name__)(request, workspace, editor, editor_test_data, runner.tests) return shared_run setattr(self.obj, name, make_func()) @@ -357,11 +366,11 @@ class EditorTestSuite(): for test_spec in tests: def make_func(test_spec): @set_marks({"runner" : runner, "test_spec" : test_spec, "run_type" : "result"}) - def result(self, request, workspace, editor, editor_test_results, launcher_platform): - # The runner must have filled the editor_test_results dict fixture for this test. + def result(self, request, workspace, editor, editor_test_data, launcher_platform): + # The runner must have filled the editor_test_data.results dict fixture for this test. # Hitting this assert could mean if there was an error executing the runner - assert test_spec.__name__ in editor_test_results, f"No run data for test: {test_spec.__name__}." - cls._report_result(test_spec.__name__, editor_test_results[test_spec.__name__]) + assert test_spec.__name__ in editor_test_data.results, f"No run data for test: {test_spec.__name__}." + cls._report_result(test_spec.__name__, editor_test_data.results[test_spec.__name__]) return result result_func = make_func(test_spec) @@ -481,41 +490,29 @@ class EditorTestSuite(): ) ] - def setup_class(cls): - cls._asset_processor = None - - def teardown_class(cls): - if cls._asset_processor: - cls._asset_processor.stop(1) - cls._asset_processor.teardown() - cls._asset_processor = None - editor_utils.kill_all_ly_processes(include_asset_processor=True) - else: - editor_utils.kill_all_ly_processes(include_asset_processor=False) - ### Utils ### # Prepares the asset processor for the test - def _prepare_asset_processor(self, workspace): + def _prepare_asset_processor(self, workspace, editor_test_data): try: # Start-up an asset processor if we are not running one # If another AP process exist, don't kill it, as we don't own it - if self._asset_processor is None: + if editor_test_data.asset_processor is None: if not process_utils.process_exists("AssetProcessor", ignore_extensions=True): - editor_utils.kill_all_ly_processes() - self._asset_processor = AssetProcessor(workspace) - self._asset_processor.start() + editor_utils.kill_all_ly_processes(include_asset_processor=True) + editor_test_data.asset_processor = AssetProcessor(workspace) + editor_test_data.asset_processor.start() else: editor_utils.kill_all_ly_processes(include_asset_processor=False) else: # Make sure the asset processor from before wasn't closed by accident - self._asset_processor.start() + editor_test_data.asset_processor.start() except Exception as ex: - self._asset_processor = None + editor_test_data.asset_processor = None raise ex - def _setup_editor_test(self, editor, workspace): - self._prepare_asset_processor(workspace) + def _setup_editor_test(self, editor, workspace, editor_test_data): + self._prepare_asset_processor(workspace, editor_test_data) editor_utils.kill_all_ly_processes(include_asset_processor=False) editor.configure_settings() @@ -555,8 +552,11 @@ class EditorTestSuite(): json_output = json_result["output"] # Cut the editor log so it only has the output for this run - m = json_result["log_match"] - end = m.end() if test_spec != test_spec_list[-1] else -1 + if "log_match" in json_result: + m = json_result["log_match"] + end = m.end() if test_spec != test_spec_list[-1] else -1 + else: + end = -1 cur_log = editor_log_content[log_start : end] log_start = end @@ -681,40 +681,38 @@ class EditorTestSuite(): for key, result in results.items(): if isinstance(result, Result.Unknown): results[key] = Result.Timeout.create(result.output, total_timeout, result.editor_log) + # FIX-ME return results # Runs a single test with the given specs, used by the collector to register the test - def _run_single_test(self, request, workspace, editor, editor_test_results, test_spec : EditorTestBase): - self._setup_editor_test(editor, workspace) + def _run_single_test(self, request, workspace, editor, editor_test_data, test_spec : EditorTestBase): + self._setup_editor_test(editor, workspace, editor_test_data) extra_cmdline_args = [] if hasattr(test_spec, "extra_cmdline_args"): extra_cmdline_args = test_spec.extra_cmdline_args results = self._exec_editor_test(request, workspace, editor, 1, "editor_test.log", test_spec, extra_cmdline_args) - if not hasattr(self.__class__, "_results"): - self.__class__._results = {} - - editor_test_results.update(results) + editor_test_data.results.update(results) test_name, test_result = next(iter(results.items())) self._report_result(test_name, test_result) # Runs a batch of tests in one single editor with the given spec list - def _run_batched_tests(self, request, workspace, editor, editor_test_results, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): + def _run_batched_tests(self, request, workspace, editor, editor_test_data, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): if not test_spec_list: return - self._setup_editor_test(editor, workspace) + self._setup_editor_test(editor, workspace, editor_test_data) results = self._exec_editor_multitest(request, workspace, editor, 1, "editor_test.log", test_spec_list, extra_cmdline_args) assert results is not None - editor_test_results.update(results) + editor_test_data.results.update(results) # Runs multiple editors with one test on each editor - def _run_parallel_tests(self, request, workspace, editor, editor_test_results, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): + def _run_parallel_tests(self, request, workspace, editor, editor_test_data, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): if not test_spec_list: return - self._setup_editor_test(editor, workspace) + self._setup_editor_test(editor, workspace, editor_test_data) parallel_editors = self._get_number_parallel_editors(request) assert parallel_editors > 0, "Must have at least one editor" @@ -744,14 +742,14 @@ class EditorTestSuite(): t.join() for result in results_per_thread: - editor_test_results.update(result) + editor_test_data.results.update(result) # Runs multiple editors with a batch of tests for each editor - def _run_parallel_batched_tests(self, request, workspace, editor, editor_test_results, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): + def _run_parallel_batched_tests(self, request, workspace, editor, editor_test_data, test_spec_list : List[EditorTestBase], extra_cmdline_args=[]): if not test_spec_list: return - self._setup_editor_test(editor, workspace) + self._setup_editor_test(editor, workspace, editor_test_data) total_threads = self._get_number_parallel_editors(request) assert total_threads > 0, "Must have at least one editor" threads = [] @@ -781,11 +779,11 @@ class EditorTestSuite(): t.join() for result in results_per_thread: - editor_test_results.update(result) + editor_test_data.results.update(result) # Retrieves the number of parallel preference cmdline overrides def _get_number_parallel_editors(self, request): - parallel_editors_value = request.config.getoption("parallel_editors", None) + parallel_editors_value = request.config.getoption("--editors-parallel", None) if parallel_editors_value: return int(parallel_editors_value) From ef5b49fc2b588938df7db3e886a78e21d476a42c Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Tue, 24 Aug 2021 14:10:39 -0500 Subject: [PATCH 27/27] Adjust the sharpness of TAA's Catmull-Rom filter based on local area luminance (#3400) * Adjust the sharpness of TAA's Catmull-Rom filter based on local area luminance. This helps prevent ringing artifacts in high contrast areas. Due to Catmull-Rom's use of negative weights, it's possible to have a very high value neighbor sample with a negative weight completely overwhelm the result leading to a negative output. This change reduces the sharpness of the catmull rom filter in high contrast areas so the negative weights contribute less to the final result. Signed-off-by: Ken Pruiksma * PR review feedback fixes - more comments and updated the way the sharpness equation was written for clarity. Signed-off-by: Ken Pruiksma --- .../Assets/Shaders/PostProcessing/Taa.azsl | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl index 2fb0b622ed..43c59cd62d 100644 --- a/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl +++ b/Gems/Atom/Feature/Common/Assets/Shaders/PostProcessing/Taa.azsl @@ -99,11 +99,23 @@ float3 YCoCgToRgb(float3 yCoCg) // This function samples a 4x4 neighborhood around the uv. By taking advantage of bilinear filtering this can be // done with only 9 taps on the edges between pixels. The cost is further reduced by dropping the 4 diagonal // samples as their influence is negligible. -float4 SampleCatmullRom5Tap(Texture2D texture, SamplerState linearSampler, float2 uv, float2 textureSize, float2 rcpTextureSize, float sharpness) +float3 SampleCatmullRom5Tap(Texture2D texture, SamplerState linearSampler, float2 uv, float2 textureSize, float2 rcpTextureSize, float sharpness) { // Think of sample locations in the 4x4 neighborhood as having a top left coordinate of 0,0 and // a bottom right coordinate of 3,3. + // Due to Catmull-Rom's use of negative weights, it's possible to have a very high value + // neighbor sample that turns into a large negative value when multiplied by its weight. + // This can completely overwhelm the final result leading to negative output. To fix this, + // use the local area green value as a measurement of luminance, and tweak the sharpness + // based on the difference between the max and min values. This will reduce the contribution + // of negative weights in high contrast areas and help prevent ringing artifacts. + float4 gatheredGreen = texture.GatherGreen(linearSampler, uv, int2(0, 0)); + float minGreen = min(gatheredGreen.x, min(gatheredGreen.y, min(gatheredGreen.z, gatheredGreen.w))); + float maxGreen = max(gatheredGreen.x, max(gatheredGreen.y, max(gatheredGreen.z, gatheredGreen.w))); + float diff = maxGreen - minGreen; + sharpness = sharpness / (diff + 1.0); + // Find the position in texture space then round it to get the center of the 1,1 pixel (tc1) float2 texelPos = uv * textureSize; float2 tc1= floor(texelPos - 0.5) + 0.5; @@ -117,7 +129,6 @@ float4 SampleCatmullRom5Tap(Texture2D texture, SamplerState linearSample float2 w1 = 1.0 + f * f * (c -3.0 + (2.0 - c) * f); float2 w2 = f * (c + f * ((3.0 - 2.0 * c) - (2.0 - c) * f)); float2 w3 = f * f * (c * f - c); - float2 w12 = w1 + w2; // Compute uv coordinates for sampling the texture @@ -135,12 +146,12 @@ float4 SampleCatmullRom5Tap(Texture2D texture, SamplerState linearSample // total weight of samples to normalize result. float totalWeight = sw0 + sw1 + sw2 + sw3 + sw4; - float4 result = 0.0f; - result += texture.SampleLevel(linearSampler, float2(tc12.x, tc0.y), 0.0) * sw0; - result += texture.SampleLevel(linearSampler, float2( tc0.x, tc12.y), 0.0) * sw1; - result += texture.SampleLevel(linearSampler, float2(tc12.x, tc12.y), 0.0) * sw2; - result += texture.SampleLevel(linearSampler, float2( tc3.x, tc12.y), 0.0) * sw3; - result += texture.SampleLevel(linearSampler, float2(tc12.x, tc3.y), 0.0) * sw4; + float3 result = 0.0; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc0.y), 0.0).rgb * sw0; + result += texture.SampleLevel(linearSampler, float2( tc0.x, tc12.y), 0.0).rgb * sw1; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc12.y), 0.0).rgb * sw2; + result += texture.SampleLevel(linearSampler, float2( tc3.x, tc12.y), 0.0).rgb * sw3; + result += texture.SampleLevel(linearSampler, float2(tc12.x, tc3.y), 0.0).rgb * sw4; return result / totalWeight; } @@ -217,7 +228,7 @@ void MainCS( float2 previousPositionOffsetInPixels = float2(PassSrg::m_constantData.m_inputColorSize) * previousPositionOffset; // Sample the last frame using a 5-tap Catmull-Rom - float3 lastFrameColor = SampleCatmullRom5Tap(PassSrg::m_lastFrameAccumulation, PassSrg::LinearSampler, uvOld, PassSrg::m_constantData.m_inputColorSize, PassSrg::m_constantData.m_inputColorRcpSize, 0.5).rgb; + float3 lastFrameColor = SampleCatmullRom5Tap(PassSrg::m_lastFrameAccumulation, PassSrg::LinearSampler, uvOld, PassSrg::m_constantData.m_inputColorSize, PassSrg::m_constantData.m_inputColorRcpSize, 0.5); lastFrameColor = RgbToYCoCg(lastFrameColor); // Last frame color relative to mean @@ -250,8 +261,8 @@ void MainCS( // Blend should be in perceptual space, so tonemap first float luminance = GetLuminance(thisFrameColor); - thisFrameColor = thisFrameColor / (1 + luminance); - lastFrameClampedColor = lastFrameClampedColor / (1 + luminance); + thisFrameColor = thisFrameColor / (1.0 + luminance); + lastFrameClampedColor = lastFrameClampedColor / (1.0 + luminance); // Blend color with history float3 color = lerp(lastFrameClampedColor, thisFrameColor, currentFrameWeight);