diff --git a/Code/Framework/AzCore/AzCore/Serialization/EditContext.h b/Code/Framework/AzCore/AzCore/Serialization/EditContext.h index ed19130579..394a6f047c 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/EditContext.h +++ b/Code/Framework/AzCore/AzCore/Serialization/EditContext.h @@ -127,13 +127,14 @@ namespace AZ */ class EditContext { + public: /// @cond EXCLUDE_DOCS class ClassBuilder; class EnumBuilder; using ClassInfo = ClassBuilder; ///< @deprecated Use EditContext::ClassBuilder using EnumInfo = EnumBuilder; ///< @deprecated Use EditContext::EnumBuilder /// @endcond - public: + AZ_CLASS_ALLOCATOR(EditContext, SystemAllocator, 0); /** @@ -186,6 +187,7 @@ namespace AZ * look at the unit tests and example to see use cases. * */ + public: class ClassBuilder { friend EditContext; @@ -399,6 +401,7 @@ namespace AZ EnumBuilder* Value(const char* name, E value); }; + private: typedef AZStd::list ClassDataListType; typedef AZStd::unordered_map EnumDataMapType; diff --git a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h index 6806232337..279ce01039 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h +++ b/Code/Framework/AzCore/AzCore/Serialization/SerializeContext.h @@ -101,6 +101,9 @@ namespace AZ class SerializeContext : public ReflectContext { + static const unsigned int VersionClassDeprecated = (unsigned int)-1; + + public: /// @cond EXCLUDE_DOCS friend class EditContext; class ClassBuilder; @@ -108,9 +111,6 @@ namespace AZ /// @endcond class EnumBuilder; - static const unsigned int VersionClassDeprecated = (unsigned int)-1; - - public: class ClassData; struct EnumerateInstanceCallContext; struct ClassElement; @@ -1131,6 +1131,7 @@ namespace AZ * ->Version(3,&MyVersionConverter) * ->Field("data",&MyStruct::m_data); */ + public: class ClassBuilder { friend class SerializeContext; @@ -1330,7 +1331,8 @@ namespace AZ AZStd::vector* m_currentAttributes = nullptr; }; - EditContext* m_editContext; ///< Pointer to optional edit context. + private: + EditContext* m_editContext; ///< Pointer to optional edit context. UuidToClassMap m_uuidMap; ///< Map for all class in this serialize context AZStd::unordered_multimap m_classNameToUuid; /// Map all class names to their uuid AZStd::unordered_multimap m_uuidGenericMap; ///< Uuid to ClassData map of reflected classes with GenericTypeInfo diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 6f28cbfe19..616be11dd0 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -91,7 +91,8 @@ AZ_POP_DISABLE_WARNING #include #include -//// + AZ_CVAR(bool, g_disableDeprecatedNodeUpdates, false, {}, AZ::ConsoleFunctorFlags::Null, + "Disables automatic update attempts of deprecated nodes, so that graphs that require and update can be viewed in their original form"); namespace EditorGraphCpp { @@ -3642,7 +3643,7 @@ namespace ScriptCanvasEditor if (scriptCanvasNode) { - if (scriptCanvasNode->IsDeprecated()) + if (scriptCanvasNode->IsDeprecated() && !g_disableDeprecatedNodeUpdates) { ScriptCanvas::NodeConfiguration nodeConfig = scriptCanvasNode->GetReplacementNodeConfiguration(); if (nodeConfig.IsValid()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja index 202fad5b60..313fd196b0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Header.jinja @@ -22,6 +22,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #pragma once +#include +#include +#include +#include + #include #include @@ -43,6 +48,11 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. {% endif %} {% endif %} +{%- set attribute_Base = Class.attrib['Base'] %} +{% if not Class.attrib['Base'] is defined %} +{% set attribute_Base = "ScriptCanvas::Nodeable" %} +{% endif %} + {% if attribute_Namespace is defined %} namespace {{attribute_Namespace}} { @@ -66,6 +76,9 @@ namespace {{attribute_Namespace}} public: \ AZ_RTTI({{className}}, "{{nodeableClassName|createHashGuid}}"{% if Class.attrib['Base'] is defined %}, {{ Class.attrib['Base'] }}{% endif %}); \ static void Reflect(AZ::ReflectContext* reflection); \ + static void ExtendReflectionSerialize([[maybe_unused]] AZ::SerializeContext::ClassBuilder* builder){% if Class.attrib['ExtendReflectionSerialize'] is defined %};{% else %}{}{% endif %} \ + static void ExtendReflectionEdit([[maybe_unused]] AZ::EditContext::ClassBuilder* builder){% if Class.attrib['ExtendReflectionEdit'] is defined %};{% else %}{}{% endif %} \ + static void ExtendReflectionBehavior([[maybe_unused]] AZ::BehaviorContext::ClassBuilder<{{className}}>* builder){% if Class.attrib['ExtendReflectionBehavior'] is defined %};{% else %}{}{% endif %} \ static const char* GetDescription() { return "{{ macros.GetAttributeAsString(Class.attrib, 'Description') }}"; } \ ScriptCanvas::NodePropertyInterface* GetPropertyInterface(AZ::Crc32 propertyId) override; \ bool IsActive() const override { return false; } \ @@ -83,13 +96,33 @@ public: \ AZ_COMPONENT({{nodeableNodeName}}, {% if Class.attrib['NodeableUuid'] is defined %}"{{Class.attrib['NodeableUuid']}}"{% else %}"{{nodeableNodeName|createHashGuid}}"{% endif %}, ScriptCanvas::Nodes::NodeableNode); static void Reflect(AZ::ReflectContext* context); + + static void ExtendReflectionSerialize([[maybe_unused]] AZ::SerializeContext::ClassBuilder* builder){% if Class.attrib['ExtendReflectionSerialize'] is defined %};{% else %}{}{% endif %} + + static void ExtendReflectionEdit([[maybe_unused]] AZ::EditContext::ClassBuilder* builder){% if Class.attrib['ExtendReflectionEdit'] is defined %};{% else %}{}{% endif %} + + static void ExtendReflectionBehavior([[maybe_unused]] AZ::BehaviorContext::ClassBuilder<{{nodeableNodeName}}>* builder){% if Class.attrib['ExtendReflectionBehavior'] is defined %};{% else %}{}{% endif %} + void ConfigureSlots() override; + +{% if Class.attrib['ExtendConfigureSlots'] is defined %} + void ExtendConfigureSlots([[maybe_unused]] SlotExecution::Ins& ins, [[maybe_unused]] SlotExecution::Outs& latents); + +{% else %} + /* no slot configuration extension, Use Class attribute 'ExtendConfigureSlots' to extend them */ + +{% endif %} void ConfigureVisualExtensions() override; + size_t GenerateFingerprint() const override; -{% if Class.attrib['EntryPoint'] is defined and Class.attrib['EntryPoint'] == "true" %} + +{% if Class.attrib['EntryPoint'] is defined and Class.attrib['EntryPoint'] == "true" %} bool IsEntryPoint() const override { return true; } -{% endif %} + +{% endif %} {{nodeableNodeName}}(); + + {{Class.attrib['NodeDeclarations']}} }; } {% endif %} @@ -100,6 +133,5 @@ public: \ {{ macros.ReportErrors() }} - {% endfor %} -{% endfor %} +{% endfor %} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja index 71681ed73b..b977daf43b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja @@ -19,15 +19,10 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -#include -#include -#include - #include #include #include #include - #include {% for xml in dataFiles %} @@ -47,13 +42,18 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. {%- set attribute_Category = Class.attrib['Category'] %} {%- set attribute_Uuid = Class.attrib['Uuid'] %} {%- set attribute_Icon = Class.attrib['Icon'] %} -{%- set attribute_Base = Class.attrib['Base'] %} {%- set attribute_GeneratePropertyFriend = Class.attrib['GeneratePropertyFriend'] %} {%- set attribute_Version = Class.attrib['Version'] %} {%- set attribute_VersionConverter = Class.attrib['VersionConverter'] %} {%- set attribute_EventHandler = Class.attrib['EventHandler'] %} {%- set attribute_Deprecated = Class.attrib['Deprecated'] %} + +{%- set attribute_Base = Class.attrib['Base'] %} +{% if not Class.attrib['Base'] is defined %} +{% set attribute_Base = "ScriptCanvas::Nodeable" %} +{% endif %} + {% set attribute_Namespace = undefined %} {%- if Class.attrib['Namespace'] is defined %} {% if Class.attrib['Namespace'] != "None" %} @@ -95,19 +95,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. {{CollectDisplayGroups('Output')}} {{CollectDisplayGroups('Parameter')}} -{# FOR DEBUGGING / DIAGNOSTIC - -// Standalone (No DisplayGroup) {{ global_standaloneTagMap }} -{% for key, value in global_standaloneTagMap.items() %} -// {{key}} : {{value}} -{% endfor %} - -// DisplayGrouped {{ global_displayGroupMap }} -{% for key, value in global_displayGroupMap.items() %} -// {{key}} : {{value}} -{% endfor %} -#} - {# ----------------------------------------------------------------------------------------- #} {% if attribute_Namespace is defined %} @@ -115,33 +102,6 @@ namespace {{attribute_Namespace}} { {% endif %} -{# Standard "In" function } -{{nodemacro.FunctionSignature(attribute_QualifiedName, Class)}} -{ -{%- for parameter in Class.findall('Parameter') -%} -{% if parameter.attrib['Input'] is defined and parameter.attrib['Input'] == "True" %} - -// this->{{parameter.attrib['Name']}} = arg{{loop.index0}}; - -{%- endif -%} -{% endfor %} - -{% set returnNames = [] %} -{% set returnTypes = [] %} -{%- for return in Class.findall('Parameter') -%} -{%- if return.attrib['Output'] is defined and return.attrib['Output'] == "True" -%} -{% if returnTypes.append(return.attrib['Type']) %}{% endif %} -{% if returnNames.append("this->" + return.attrib['Name']) %}{% endif %} -{%- endif -%} -{%- endfor -%} - -{% if returnNames|length() == 1 %} -return {{returnNames[0]}}; -{% elif returnNames|length() > 1 %} - return AZStd::tuple<{{returnTypes|join(", ")}}>({{returnNames|join(", ")}}); -{% endif %} -} -#} {%- set nodeableNodeName = attribute_Name + 'Node' %} {% set list_outputs = [] %} {% for output in Class.iter('Output') %} @@ -156,43 +116,81 @@ return {{returnNames[0]}}; {% for item in Class.iter('Output') %} {% if item.attrib['DisplayGroup'] is defined %}{% set displayGroup = item.attrib['DisplayGroup'] %}{% endif %} {% endfor %} +{% set branches = [] %} +{% for method in Class.findall('Input') %} +{% for branch in method.findall('Branch') %} +{% if branches.append(branch) %}{% endif %} +{% endfor %} +{% endfor %} {# ExecutionOuts #} // ExecutionOuts begin {{ nodemacro.ExecutionOutDefinitions(Class, attribute_QualifiedName)}} +{% if not Class.attrib['ExtendConfigureSlots'] is defined %} size_t {{attribute_QualifiedName}}::GetRequiredOutCount() const { return {{Class.findall('Output')|length + branches|length}}; }{% endif %} // ExecutionOuts end {# Reflect #} + +{% if Class.attrib['ExtendReflectionSerialize'] is defined %} +{% set ExtendReflectionSerialize = "defined" %} +{% set preSerialize = "serializeBuilder" %} +{% set postSerialize = ";" %} +{% else %} +{% set preSerialize = "" %} +{% set postSerialize = "" %} +{% endif %} + +{% if Class.attrib['ExtendReflectionEdit'] is defined %} +{% set ExtendReflectionEdit = "defined" %} +{% set preEdit = "editorBuilder" %} +{% set postEdit = ";" %} +{% else %} +{% set preEdit = "" %} +{% set postEdit = "" %} +{% endif %} + +{% if Class.attrib['ExtendReflectionBehavior'] is defined %} +{% set ExtendReflectionBehavior = "defined" %} +{% set preBehavior = "behaviorBuilder" %} +{% set postBehavior = ";" %} +{% else %} +{% set preBehavior = "" %} +{% set postBehavior = "" %} +{% endif %} + void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) { using namespace ScriptCanvas; if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { - serializeContext->Class<{{ attribute_Name }}{% if attribute_Base is defined %}, {{ attribute_Base }}{% endif %}>() +{% 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 %} - ->EventHandler<{{ attribute_EventHandler }}>() + {{preSerialize}}->EventHandler<{{ attribute_EventHandler }}>(){{postSerialize}} {% endif %} {# Serialized Properties #} {% for Property in Class.iter('Property') %} {% set property_Name = Property.attrib['Name'] %} - ->Field("{{ property_Name }}", &{{ attribute_Name }}::{{ property_Name | replace(' ','') }}) + {{preSerialize}}->Field("{{ property_Name }}", &{{ attribute_Name }}::{{ property_Name | replace(' ','') }}){{postSerialize}} {% endfor %} ; +{% if ExtendReflectionSerialize is defined %} + ExtendReflectionSerialize(&{{preSerialize}}); +{% endif %} + if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class<{{ attribute_QualifiedName }}>("{{ attribute_PreferredClassName }}", "{{ attribute_Description }}") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - +{% if ExtendReflectionEdit is defined %} auto {{preEdit}} = {% else %} {% endif %}editContext->Class<{{ attribute_QualifiedName }}>("{{ attribute_PreferredClassName }}", "{{ attribute_Description }}"){{postEdit}} + {{preEdit}}->ClassElement(AZ::Edit::ClassElements::EditorData, ""){{postEdit}} + {{preEdit}}->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly){{postEdit}} {% if attribute_Category is defined %} - ->Attribute(AZ::Edit::Attributes::Category, "{{ attribute_Category }}") + {{preEdit}}->Attribute(AZ::Edit::Attributes::Category, "{{ attribute_Category }}"){{postEdit}} {%- endif %} {% if attribute_Icon is defined %} - ->Attribute(AZ::Edit::Attributes::Icon, "{{ attribute_Icon }}") + {{preEdit}}->Attribute(AZ::Edit::Attributes::Icon, "{{ attribute_Icon }}"){{postEdit}} {%- endif %} {% if attribute_Deprecated is defined %} - ->Attribute(AZ::Edit::Attributes::Deprecated, "{{ attribute_Deprecated }}") + {{preEdit}}->Attribute(AZ::Edit::Attributes::Deprecated, "{{ attribute_Deprecated }}"){{postEdit}} {%- endif %} {% set uihandler = 'AZ::Edit::UIHandlers::Default' %} {% for item in Class.iter('Property') %} @@ -203,29 +201,34 @@ void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) {% if item.attrib['Description'] is defined %} {% set description = item.attrib['Description'] %} {% endif %} - // {{ item.attrib['Name'] }} - ->DataElement({{ uihandler }}, &{{ attribute_Name }}::{{ item.attrib['Name'] }}, "{{ item.attrib['Name'] }}", "{{ description }}") + // {{ item.attrib['Name'] }} + {{preEdit}}->DataElement({{ uihandler }}, &{{ attribute_Name }}::{{ item.attrib['Name'] }}, "{{ item.attrib['Name'] }}", "{{ description }}"){{postEdit}} {% for EditAttribute in item.iter('EditAttribute') %} - ->Attribute({{ EditAttribute.attrib['Key'] }}, {{ EditAttribute.attrib['Value'] }}) + {{preEdit}}->Attribute({{ EditAttribute.attrib['Key'] }}, {{ EditAttribute.attrib['Value'] }}){{postEdit}} {% endfor %} {% endfor %} ; +{% if ExtendReflectionEdit is defined %} + ExtendReflectionEdit(&{{preEdit}}); +{% endif %} } } // Behavior Context Reflection if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { - behaviorContext->Class<{{ attribute_Name }}>("{{ attribute_Name }}") - ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List) - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) +{% if ExtendReflectionBehavior is defined %} auto {{preBehavior}} = {% else %} {% endif %}behaviorContext->Class<{{ attribute_Name }}>("{{ attribute_Name }}"){{postBehavior}} + {{preBehavior}}->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List){{postBehavior}} + {{preBehavior}}->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common){{postBehavior}} {% for inputMethod in Class.iter('Input') %} {% set methodName = inputMethod.attrib['Name'] %} // {{ inputMethod.attrib['Name'] }} - ->Method(Grammar::ToIdentifier("{{ macros.SlotName(methodName) }}").c_str(), &{{ attribute_Name }}::{{ macros.CleanName(methodName) }}) + {{preBehavior}}->Method(Grammar::ToIdentifier("{{ macros.SlotName(methodName) }}").c_str(), &{{ attribute_Name }}::{{ macros.CleanName(methodName) }}){{postBehavior}} {% endfor %} - ; +{% if ExtendReflectionBehavior is defined %} + ExtendReflectionBehavior(&{{preBehavior}}); +{% endif %} } } @@ -253,27 +256,32 @@ Nodes::{{ nodeableNodeName }}::{{ nodeableNodeName }}() {# NodeableNode Reflection #} void Nodes::{{ nodeableNodeName }}::Reflect(AZ::ReflectContext* context) { - {{ attribute_QualifiedName }}::Reflect(context); // Serialization Context Reflection if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { - serializeContext->Class<{{ nodeableNodeName }}, NodeableNode>() + {%if ExtendReflectionSerialize is defined%}auto {{preSerialize}} = {%endif%}serializeContext->Class<{{ nodeableNodeName }}, NodeableNode>(){{postSerialize}} {% if attribute_Version is defined %} - ->Version({{ attribute_Version }}{% if attribute_VersionConverter is defined %}, &{{ attribute_VersionConverter }}{% endif %}) + {{preSerialize}}->Version({{ attribute_Version }}{% if attribute_VersionConverter is defined %}, &{{ attribute_VersionConverter }}{% endif %}){{postSerialize}} {% else %} - ->Version(0) + {{preSerialize}}->Version(0){{postSerialize}} +{% endif %} + ; +{% if ExtendReflectionSerialize is defined %} + ExtendReflectionSerialize(&{{preSerialize}}); {% endif %} - ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) { - editContext->Class<{{ nodeableNodeName }}>("{{ attribute_PreferredClassName }}", "{{ attribute_Description }}") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ; + {% if ExtendReflectionEdit is defined %}auto {{preEdit}} = {%endif%}editContext->Class<{{ nodeableNodeName }}>("{{ attribute_PreferredClassName }}", "{{ attribute_Description }}"){{postEdit}} + {{preEdit}}->ClassElement(AZ::Edit::ClassElements::EditorData, ""){{postEdit}} + {{preEdit}}->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly){{postEdit}} + {{preEdit}}->Attribute(AZ::Edit::Attributes::AutoExpand, true){{postEdit}} + ; +{% if ExtendReflectionEdit is defined %} + ExtendReflectionEdit(&{{preEdit}}); +{% endif %} } } } @@ -324,6 +332,7 @@ void Nodes::{{ nodeableNodeName }}::ConfigureVisualExtensions() RegisterExtension(visualExtensions); } {% endfor %} + OnConfigureVisualExtensions(); } {# ConfigureSlots #} @@ -457,6 +466,9 @@ void Nodes::{{ nodeableNodeName }}::ConfigureSlots() {% endfor %} #} +{% if Class.attrib['ExtendConfigureSlots'] is defined %} + ExtendConfigureSlots(ins, outs); +{% endif %} // Generate the execution map m_slotExecutionMap = SlotExecution::Map(AZStd::move(ins), AZStd::move(outs)); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja index addd24f5d3..a7300791e8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja @@ -349,7 +349,4 @@ void {{qualifiedName}}::Call{{CleanName(outName)}}({{ExecutionOutReturnDefinitio {%- for executionOut in Class.findall('Output') -%} {{ ExecutionOutDefinition(Class, qualifiedName, executionOut, loop.index0 + branches|length) }} {%- endfor %} - -size_t {{qualifiedName}}::GetRequiredOutCount() const { return {{Class.findall('Output')|length + branches|length}}; } - -{% endmacro %} +{% endmacro %} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index 5b1e5eee76..8f3cefa138 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -250,7 +250,6 @@ namespace ScriptCanvas }; using ScriptCanvasSettingsRequestBus = AZ::EBus; - } namespace AZStd diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index 30e55cee49..64c9f2497d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -1476,9 +1476,11 @@ namespace ScriptCanvas const void* Datum::GetValueAddress() const { - return m_type.GetType() != Data::eType::BehaviorContextObject - ? AZStd::any_cast(&m_storage) - : (*AZStd::any_cast(&m_storage))->Get(); + return !m_storage.empty() + ? m_type.GetType() != Data::eType::BehaviorContextObject + ? AZStd::any_cast(&m_storage) + : (*AZStd::any_cast(&m_storage))->Get() + : nullptr; } bool Datum::Initialize(const Data::Type& type, eOriginality originality, const void* source, const AZ::Uuid& sourceTypeID) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index 781dcb9ed8..be6f3ee37e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -389,7 +389,7 @@ namespace ScriptCanvas bool Datum::Empty() const { - return GetValueAddress() == nullptr; + return m_storage.empty() || GetValueAddress() == nullptr; } template diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 4a936c8824..98d5e6b121 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -3577,12 +3577,12 @@ namespace ScriptCanvas } if (targetSlotType == CombinedSlotType::DataOut - && executionSlot.GetType() == CombinedSlotType::ExecutionIn - && executionInCount > 1) + && executionSlot.GetType() == CombinedSlotType::ExecutionIn + && executionInCount > 1) { if (!executionChildSlot || executionChildSlot->GetType() != CombinedSlotType::ExecutionOut) { - return AZ::Failure(AZStd::string("Data out by ExcutionIn must have child out slot")); + return AZ::Failure(AZStd::string("Data out by ExecutionIn must have child out slot")); } } @@ -3626,6 +3626,11 @@ namespace ScriptCanvas return {}; } + Grammar::MultipleFunctionCallFromSingleSlotInfo Node::GetMultipleFunctionCallFromSingleSlotInfo([[maybe_unused]] const Slot& slot) const + { + return {}; + } + VariableId Node::GetVariableIdRead(const Slot*) const { return {}; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index a2d06686e9..42ffaec8da 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -715,6 +715,8 @@ namespace ScriptCanvas virtual PropertyFields GetPropertyFields() const; + virtual Grammar::MultipleFunctionCallFromSingleSlotInfo GetMultipleFunctionCallFromSingleSlotInfo(const Slot& slot) const; + virtual VariableId GetVariableIdRead(const Slot*) const; virtual VariableId GetVariableIdWritten(const Slot*) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h index 0193641d97..c1c9db6f8b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h @@ -73,6 +73,8 @@ namespace ScriptCanvas void ConfigureSlots() override; + virtual void OnConfigureVisualExtensions() {} + AZ::Outcome GetBehaviorContextClass() const; ConstSlotsOutcome GetBehaviorContextOutName(const Slot& inSlot) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h index 8426e90515..7b74f3dd81 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/PureData.h @@ -46,6 +46,8 @@ namespace ScriptCanvas const AZStd::unordered_map>& GetPropertyNameSlotMap() const; + AZ_INLINE AZ::Outcome GetDependencies() const override { return AZ::Success(DependencyReport{}); } + ~PureData() override; protected: diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 732455857e..db45f6bfe3 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -2249,6 +2249,10 @@ namespace ScriptCanvas } #endif AddAllVariablesPreParse(); + if (!IsErrorFree()) + { + return; + } for (auto& nodeEntity : m_source.m_graphData->m_nodes) { @@ -2270,6 +2274,16 @@ namespace ScriptCanvas { AddError(nullptr, ValidationConstPtr(aznew NullEntityInGraph())); } + + if (!IsErrorFree()) + { + return; + } + } + + if (!IsErrorFree()) + { + return; } ParseAutoConnectedEBusHandlerVariables(); @@ -2638,7 +2652,8 @@ namespace ScriptCanvas AZStd::vector inputVariableIds; AZStd::unordered_map inputVariablesById; - for (auto variable : GetVariables()) + auto& variables = GetVariables(); + for (auto variable : variables) { auto constructionRequirement = ParseConstructionRequirement(variable); @@ -2655,18 +2670,30 @@ namespace ScriptCanvas case VariableConstructionRequirement::InputNodeable: { + if (variable->m_datum.Empty()) + { + AddError(nullptr, aznew Internal::ParseError(AZ::EntityId{}, "Empty nodeable datum in variable, probably due to a problem with azrtti declarations")); + break; + } + // I solemnly swear no harm shall come to the nodeable const Nodeable* nodeableSource = reinterpret_cast(variable->m_datum.GetAsDanger()); - AZ_Assert(nodeableSource != nullptr, "the must be a raw nodeable held by this pointer"); - AZ_Assert(azrtti_typeid(nodeableSource) != azrtti_typeid(), "type problem with nodeable"); + + if (!nodeableSource) + { + AddError(nullptr, aznew Internal::ParseError(AZ::EntityId{}, "No raw nodeable held by variable")); + break; + } + nodeablesById.push_back({ variable->m_nodeableNodeId, const_cast(nodeableSource) }); } break; case VariableConstructionRequirement::InputVariable: { - inputVariableIds.push_back(variable->m_sourceVariableId); - inputVariablesById.insert({ variable->m_sourceVariableId, variable }); + auto variableID = variable->m_sourceVariableId.IsValid() ? variable->m_sourceVariableId : VariableId::MakeVariableId(); + inputVariableIds.push_back(variableID); + inputVariablesById.insert({ variableID, variable }); // sort revealed a datum copy issue: type is not preserved, workaround below // m_runtimeInputs.m_variables.emplace_back(variable->m_sourceVariableId, variable->m_datum); } @@ -4310,6 +4337,7 @@ namespace ScriptCanvas { if (auto variable = FindVariable(execution->GetNodeId())) { + execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); } else @@ -4327,6 +4355,7 @@ namespace ScriptCanvas { auto variable = AZStd::make_shared(); variable->m_datum = Datum(eventHandling->m_handlerName); + execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); } else @@ -4338,6 +4367,7 @@ namespace ScriptCanvas { if (auto variable = FindVariable(execution->GetNodeId())) { + execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); } else @@ -4367,12 +4397,159 @@ namespace ScriptCanvas void AbstractCodeModel::ParseMultiExecutionPost(ExecutionTreePtr execution) { ParsePropertyExtractionsPost(execution); + ParseMultipleFunctionCallPost(execution); } void AbstractCodeModel::ParseMultiExecutionPre(ExecutionTreePtr execution) { ParsePropertyExtractionsPre(execution); - } + } + + void AbstractCodeModel::ParseMultipleFunctionCallPost(ExecutionTreePtr execution) + { + auto& id = execution->GetId(); + MultipleFunctionCallFromSingleSlotInfo info = id.m_node->GetMultipleFunctionCallFromSingleSlotInfo(*id.m_slot); + + if (info.functionCalls.empty()) + { + return; + } + + auto parent = execution->ModParent(); + + if (!parent) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), "Null parent in MultipleFunctionCall")); + return; + } + + size_t indexInParentCall = parent->FindChildIndex(execution); + if (indexInParentCall >= parent->GetChildrenCount()) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotNoChildren)); + return; + } + + ExecutionChild* executionChildInParent = &parent->ModChild(indexInParentCall); + + const size_t executionInputCount = execution->GetInputCount(); + const size_t thisInputOffset = execution->InputHasThisPointer() ? 1 : 0; + + // the original index has ALL the input from the slots on the node + // create multiple calls with separate function call nodes, but ONLY take the inputs required + // as indicated by the function call info + + AZStd::unordered_set usedSlots; + bool variadicIsFound = false; + + auto createChild = [&](auto parentCall, ExecutionChild* childInParent, auto& functionCallInfo) + { + auto child = CreateChild(parentCall, id.m_node, id.m_slot); + child->SetSymbol(Symbol::FunctionCall); + child->SetName(functionCallInfo.functionName); + child->SetNameLexicalScope(functionCallInfo.lexicalScope); + childInParent->m_execution = child; + return child; + }; + + auto addThisInput = [&](auto functionCall) + { + if (thisInputOffset != 0) + { + if (executionInputCount == 0) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotNotEnoughInputForThis)); + return; + } + + const ExecutionInput& input = execution->GetInput(0); + usedSlots.insert(input.m_slot); + functionCall->AddInput(input); + } + }; + + auto addSlotInput = [&](auto functionCall, size_t inputIndex) + { + if (inputIndex >= executionInputCount) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotNotEnoughInput)); + return; + } + + const ExecutionInput& input = execution->GetInput(inputIndex); + + if (usedSlots.contains(input.m_slot)) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotNotEnoughInput)); + return; + } + + usedSlots.insert(input.m_slot); + + if (input.m_value->m_source == execution) + { + input.m_value->m_source = functionCall; + } + + functionCall->AddInput(input); + }; + + auto addCall = [&](auto& functionCallInfo, auto childInParent, size_t startingIndex, size_t sentinel, size_t variadicOffset = 0) + { + auto child = createChild(parent, childInParent, functionCallInfo); + addThisInput(child); + + for (size_t index = startingIndex; index < sentinel; ++index) + { + const size_t inputIndex = index + thisInputOffset + variadicOffset; + addSlotInput(child, inputIndex); + } + + child->AddChild({}); + childInParent = &child->ModChild(0); + return AZStd::make_pair(childInParent, child); + }; + + // loop through each call... + for (auto& functionCallInfo : info.functionCalls) + { + // ...first add any pre-variadic calls, using the starting index and the number of args, since they could come in any order, not input slot order... + if (!functionCallInfo.isVariadic) + { + AZStd::pair childInParentAndParent = addCall(functionCallInfo, executionChildInParent, functionCallInfo.startingIndex, functionCallInfo.startingIndex + functionCallInfo.numArguments); + executionChildInParent = childInParentAndParent.first; + parent = childInParentAndParent.second; + } + else + { + // ...then add only one variadic call if there is one... + if (variadicIsFound) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotMultipleVariadic)); + return; + } + + variadicIsFound = true; + const size_t sentinel = executionInputCount == 0 ? 0 : executionInputCount - thisInputOffset; + // ... by looping through the remaining slots, striding by functionCallInfo.numArguments, making repeated calls to the function + for (size_t slotInputIndex = functionCallInfo.startingIndex; slotInputIndex < sentinel; slotInputIndex += functionCallInfo.numArguments) + { + AZStd::pair childInParentAndParent = addCall(functionCallInfo, executionChildInParent, 0, functionCallInfo.numArguments, slotInputIndex); + executionChildInParent = childInParentAndParent.first; + parent = childInParentAndParent.second; + } + } + } + + if (info.errorOnUnusedSlot && usedSlots.size() != executionInputCount) + { + AddError(execution, aznew Internal::ParseError(id.m_node->GetEntityId(), ParseErrors::MultipleFunctionCallFromSingleSlotUnused)); + } + + // parent now refers to the last child call created + parent->SwapChildren(execution); + execution->Clear(); + } void AbstractCodeModel::ParseNodelingVariables(const Node& node, NodelingType nodelingType) { @@ -5146,6 +5323,6 @@ namespace ScriptCanvas return type == Data::eType::BehaviorContextObject; } - } + } -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index f1ad7b986b..8b8be27fab 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -387,6 +387,8 @@ namespace ScriptCanvas void ParseMultiExecutionPre(ExecutionTreePtr execution); + void ParseMultipleFunctionCallPost(ExecutionTreePtr execution); + void ParseNodelingVariables(const Node& node, NodelingType nodelingType); void ParseOperatorArithmetic(ExecutionTreePtr execution); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp index e16a3bc815..131209a521 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp @@ -1132,14 +1132,14 @@ namespace ScriptCanvas } else if (variable->m_isExposedToConstruction) { - if (variable->m_sourceVariableId.IsValid()) - { - return VariableConstructionRequirement::InputVariable; - } - else if (variable->m_nodeableNodeId.IsValid()) + if (variable->m_nodeableNodeId.IsValid()) { return VariableConstructionRequirement::InputNodeable; } + else if (variable->m_sourceVariableId.IsValid()) + { + return VariableConstructionRequirement::InputVariable; + } else { AZ_Assert(false, "A member variable in the model has no valid id"); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h index ab047fb580..d7e4fa0f72 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h @@ -164,6 +164,34 @@ namespace ScriptCanvas virtual void PostParseExecutionTreeBody(AbstractCodeModel& /*model*/, ExecutionTreePtr /*execution*/) {} }; + // for now, no return values supported + struct MultipleFunctionCallFromSingleSlotEntry + { + AZ_TYPE_INFO(MultipleFunctionCallFromSingleSlotEntry, "{360A23A3-C490-4047-B71E-64E290E441D3}"); + AZ_CLASS_ALLOCATOR(MultipleFunctionCallFromSingleSlotEntry, AZ::SystemAllocator, 0); + + bool isVariadic = false; + AZStd::string functionName; + LexicalScope lexicalScope; + size_t numArguments = 0; // stride in case isVariadic == true + size_t startingIndex = 0; // the index of the slot order + }; + + // for now, no return values supported + struct MultipleFunctionCallFromSingleSlotInfo + { + AZ_TYPE_INFO(MultipleFunctionCallFromSingleSlotInfo, "{DF51F08A-8B28-4851-9888-9AB7CC0B90D2}"); + AZ_CLASS_ALLOCATOR(MultipleFunctionCallFromSingleSlotInfo, AZ::SystemAllocator, 0); + + // this could likely be implemented, but needs care to duplicate input that the execution-slot created + // bool errorOnReusedSlot = false; + + bool errorOnUnusedSlot = false; + + // calls are executed in the order they arrive in the vector + AZStd::vector functionCalls; + }; + struct NodeableParse : public AZStd::enable_shared_from_this { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index ed61d7e838..66f609768d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -313,6 +313,11 @@ namespace ScriptCanvas return !m_returnValues.empty(); } + bool ExecutionTree::InputHasThisPointer() const + { + return m_inputHasThisPointer; + } + bool ExecutionTree::IsInfiniteLoopDetectionPoint() const { return m_isInfiniteLoopDetectionPoint; @@ -377,6 +382,11 @@ namespace ScriptCanvas m_isInfiniteLoopDetectionPoint = true; } + void ExecutionTree::MarkInputHasThisPointer() + { + m_inputHasThisPointer = true; + } + void ExecutionTree::MarkInputOutputPreprocessed() { m_isInputOutputPreprocessed = true; @@ -587,6 +597,32 @@ namespace ScriptCanvas m_symbol = val; } - } + void ExecutionTree::SwapChildren(ExecutionTreePtr execution) + { + if (execution) + { + m_children.swap(execution->m_children); + for (auto& child : m_children) + { + if (child.m_execution) + { + child.m_execution->SetParent(shared_from_this()); + } + } + + for (auto& orphan : execution->m_children) + { + if (orphan.m_execution) + { + orphan.m_execution->SetParent(execution); + } + } + } + else + { + ClearChildren(); + } + } + } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h index 3d0d75b313..17b86c8da4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h @@ -190,6 +190,8 @@ namespace ScriptCanvas bool HasReturnValues() const; + bool InputHasThisPointer() const; + bool IsInfiniteLoopDetectionPoint() const; void InsertChild(size_t index, const ExecutionChild& child); @@ -208,6 +210,8 @@ namespace ScriptCanvas void MarkInfiniteLoopDetectionPoint(); + void MarkInputHasThisPointer(); + void MarkInputOutputPreprocessed(); void MarkInternalOut(); @@ -262,6 +266,8 @@ namespace ScriptCanvas void SetSymbol(Symbol val); + void SwapChildren(ExecutionTreePtr execution); + private: // the (possible) slot(s) through which execution exited, along with associated output AZStd::vector m_children; @@ -275,6 +281,8 @@ namespace ScriptCanvas bool m_isInfiniteLoopDetectionPoint = false; + bool m_inputHasThisPointer = false; + bool m_isInputOutputPreprocessed = false; bool m_isInternalOut = false; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h index def4fa7761..68c6a8442a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h @@ -57,6 +57,12 @@ namespace ScriptCanvas constexpr const char* MissingVariableForEBusHandlerAddress = "missing variable for ebus handler address"; constexpr const char* MissingVariableForEBusHandlerAddressConnected = "missing variable for ebus handler address"; constexpr const char* MultipleExecutionOutConnections = "This node has multiple, unordered execution Out connections"; + constexpr const char* MultipleFunctionCallFromSingleSlotMultipleVariadic = "Only one variadic call (the last one) is supported in the multi-call per single slot."; + constexpr const char* MultipleFunctionCallFromSingleSlotNoChildren = "Node missing from parent children."; + constexpr const char* MultipleFunctionCallFromSingleSlotNotEnoughInput = "Not enough input to support multi call input information."; + constexpr const char* MultipleFunctionCallFromSingleSlotNotEnoughInputForThis = "Node doesn't have enough input for a parsed this pointer."; + constexpr const char* MultipleFunctionCallFromSingleSlotReused = "Multiple function slot reused an input slot"; + constexpr const char* MultipleFunctionCallFromSingleSlotUnused = "Multiple function slot left an input slot unused."; constexpr const char* MultipleSimulaneousInputValues = "Multiple values routed to the same single input with no way to discern which to take."; constexpr const char* MultipleStartNodes = "Multiple Start nodes in a single graph. Only one is allowed."; constexpr const char* NoChildrenAfterRoot = "No children after parsing function root"; diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_RunAllTransformNodes.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_RunAllTransformNodes.scriptcanvas index 45b24bad8d..c3b3599325 100644 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_RunAllTransformNodes.scriptcanvas +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_RunAllTransformNodes.scriptcanvas @@ -3,34 +3,34 @@ - + - + - + - + - + - + - + @@ -62,12 +62,13 @@ + - + @@ -99,12 +100,13 @@ + - + @@ -141,12 +143,13 @@ + - + @@ -178,6 +181,7 @@ + @@ -189,7 +193,7 @@ - + @@ -199,26 +203,26 @@ - + - + - + - + - + - + @@ -250,12 +254,13 @@ + - + @@ -287,12 +292,13 @@ + - + @@ -329,12 +335,646 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -371,12 +1011,13 @@ + - + @@ -408,6 +1049,7 @@ + @@ -419,7 +1061,7 @@ - + @@ -431,7 +1073,7 @@ - + @@ -441,26 +1083,26 @@ - + - + - + - + - + - + @@ -492,12 +1134,13 @@ + - + @@ -529,484 +1172,13 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1043,12 +1215,13 @@ + - + @@ -1080,21 +1253,10 @@ + - - - - - - - - - - - - @@ -1103,7 +1265,7 @@ - + @@ -1113,26 +1275,26 @@ - + - + - + - + - + - + @@ -1164,12 +1326,13 @@ + - + @@ -1201,200 +1364,13 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -1431,12 +1407,56 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1446,10 +1466,10 @@ - + - + @@ -1468,6 +1488,7 @@ + @@ -1479,9 +1500,21 @@ - + - + + + + + + + + + + + + + @@ -1489,26 +1522,26 @@ - + - + - + - + - + - + @@ -1540,12 +1573,338 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1577,12 +1936,205 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1619,12 +2171,13 @@ + - + @@ -1639,7 +2192,7 @@ - + @@ -1661,12 +2214,13 @@ + - + @@ -1676,10 +2230,10 @@ - + - + @@ -1698,6 +2252,7 @@ + @@ -1709,19 +2264,19 @@ - + - + - + @@ -1731,26 +2286,26 @@ - + - + - + - + - + - + @@ -1782,12 +2337,13 @@ + - + @@ -1819,12 +2375,13 @@ + - + @@ -1839,7 +2396,7 @@ - + @@ -1861,12 +2418,56 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1898,6 +2499,7 @@ + @@ -1909,36 +2511,107 @@ - + + + + + + + + + + + + + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1970,12 +2643,13 @@ + - + @@ -2007,12 +2681,13 @@ + - + @@ -2049,12 +2724,205 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2091,12 +2959,13 @@ + - + @@ -2128,6 +2997,7 @@ + @@ -2139,7 +3009,7 @@ - + @@ -2151,7 +3021,7 @@ - + @@ -2161,26 +3031,26 @@ - + - + - + - + - + - + @@ -2212,12 +3082,13 @@ + - + @@ -2249,12 +3120,13 @@ + - + @@ -2291,12 +3163,56 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2328,6 +3244,7 @@ + @@ -2339,36 +3256,1196 @@ - + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -2405,12 +4482,13 @@ + - + @@ -2447,12 +4525,13 @@ + - + @@ -2484,12 +4563,13 @@ + - + @@ -2521,6 +4601,7 @@ + @@ -2565,1709 +4646,26 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + @@ -4299,12 +4697,13 @@ + - + @@ -4336,12 +4735,13 @@ + - + @@ -4378,12 +4778,13 @@ + - + @@ -4420,12 +4821,13 @@ + - + @@ -4457,6 +4859,7 @@ + @@ -4480,7 +4883,7 @@ - + @@ -4490,26 +4893,26 @@ - + - + - + - + - + - + @@ -4541,12 +4944,13 @@ + - + @@ -4578,12 +4982,13 @@ + - + @@ -4620,850 +5025,13 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -5495,194 +5063,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -5694,9 +5075,9 @@ - + - + @@ -5704,703 +5085,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + @@ -6410,28 +5123,28 @@ - + - + - + - + - + - + - + @@ -6441,28 +5154,28 @@ - + - + - + - + - + - + - + @@ -6472,28 +5185,28 @@ - + - + - + - + - + - + - + @@ -6503,28 +5216,28 @@ - + - + - + - + - + - + - + @@ -6534,28 +5247,28 @@ - + - + - + - + - + - + - + @@ -6565,28 +5278,28 @@ - + - + - + - + - + - + - + @@ -6596,28 +5309,28 @@ - + - + - + - + - + - + - + @@ -6627,28 +5340,28 @@ - + - + - + - + - + - + - + @@ -6658,28 +5371,28 @@ - + - + - + - + - + - + - + @@ -6689,28 +5402,28 @@ - + - + - + - + - + - + @@ -6720,28 +5433,28 @@ - + - + - + - + - + - + - + @@ -6751,28 +5464,307 @@ - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -6788,7 +5780,7 @@ - + @@ -6796,7 +5788,7 @@ - + @@ -6804,7 +5796,7 @@ - + @@ -6822,15 +5814,15 @@ - - - + + + - - - + + + @@ -6838,7 +5830,7 @@ - + @@ -6846,7 +5838,7 @@ - + @@ -6863,46 +5855,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -6911,18 +5867,12 @@ - - - - - - - + @@ -6930,637 +5880,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -7586,7 +5906,7 @@ - + @@ -7594,7 +5914,7 @@ - + @@ -7602,7 +5922,595 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7620,15 +6528,15 @@ - - - + + + - - - + + + @@ -7636,7 +6544,7 @@ - + @@ -7644,7 +6552,7 @@ - + @@ -7661,46 +6569,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -7709,18 +6581,12 @@ - - - - - - - + @@ -7728,7 +6594,7 @@ - + @@ -7746,15 +6612,15 @@ - - - + + + - - - + + + @@ -7762,7 +6628,7 @@ - + @@ -7771,9 +6637,9 @@ - - - + + + @@ -7783,7 +6649,7 @@ - + @@ -7791,49 +6657,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -7851,15 +6675,15 @@ - - - + + + - - - + + + @@ -7867,7 +6691,7 @@ - + @@ -7875,7 +6699,49 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7893,15 +6759,15 @@ - - - + + + - - - + + + @@ -7915,60 +6781,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -7980,7 +6798,35 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7988,25 +6834,33 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + @@ -8014,7 +6868,7 @@ - +