From 961f2ef1133ec27d68cbf2d6ee0c839cdecf1760 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 20 Apr 2021 12:04:57 -0700 Subject: [PATCH] Replace string/hash based execution out look up for indices, 10-50% speed up in lookup code. Fix bugs calling dependent functions. --- .../ScriptCanvasBuilderWorkerUtility.cpp | 2 + .../FunctionNodePaletteTreeItemTypes.cpp | 4 +- .../AutoGen/ScriptCanvasNodeable_Source.jinja | 2 +- .../ScriptCanvas_Nodeable_Macros.jinja | 34 +- .../Include/ScriptCanvas/Core/EBusHandler.cpp | 14 +- .../Code/Include/ScriptCanvas/Core/Node.cpp | 44 + .../Code/Include/ScriptCanvas/Core/Node.h | 4 + .../Include/ScriptCanvas/Core/Nodeable.cpp | 83 +- .../Code/Include/ScriptCanvas/Core/Nodeable.h | 114 +- .../ScriptCanvas/Core/NodeableNode.cpp | 13 - .../Include/ScriptCanvas/Core/NodeableNode.h | 2 - .../ScriptCanvas/Core/SlotExecutionMap.cpp | 16 - .../ScriptCanvas/Core/SlotExecutionMap.h | 2 - .../ScriptCanvas/Core/SubgraphInterface.cpp | 21 +- .../ScriptCanvas/Core/SubgraphInterface.h | 4 +- .../Interpreted/ExecutionInterpretedAPI.cpp | 73 +- .../ExecutionInterpretedEBusAPI.cpp | 35 +- .../Execution/RuntimeComponent.cpp | 2 +- .../Grammar/AbstractCodeModel.cpp | 37 +- .../ScriptCanvas/Grammar/AbstractCodeModel.h | 1 + .../ScriptCanvas/Grammar/ParsingUtilities.cpp | 7 + .../ScriptCanvas/Grammar/ParsingUtilities.h | 2 + .../Include/ScriptCanvas/Grammar/Primitives.h | 2 +- .../Grammar/PrimitivesDeclarations.h | 2 +- .../Grammar/PrimitivesExecution.cpp | 10 + .../Grammar/PrimitivesExecution.h | 6 + .../Internal/Nodeables/BaseTimer.cpp | 2 +- .../Libraries/Core/EBusEventHandler.cpp | 5 + .../Libraries/Core/EBusEventHandler.h | 1 + .../Libraries/Core/ReceiveScriptEvent.cpp | 5 + .../Libraries/Core/ReceiveScriptEvent.h | 1 + .../Operators/Math/OperatorLerpNodeable.h | 9 +- .../Include/ScriptCanvas/SystemComponent.h | 2 +- .../ScriptCanvas/Translation/GraphToLua.cpp | 67 +- .../Code/Source/SystemComponent.cpp | 4 +- ..._SC_UnitTest_ExecutionCycle10.scriptcanvas | 3216 +++++++++ ...tTest_ExecutionOutPerformance.scriptcanvas | 5753 +++++++++++++++++ ...C_UnitTest_HelloWorldFunction.scriptcanvas | 628 ++ ...est_HelloWorldFunctionNotPure.scriptcanvas | 733 +++ ...tentCallOfNotPureUserFunction.scriptcanvas | 750 +++ ..._LatentCallOfPureUserFunction.scriptcanvas | 750 +++ .../Framework/ScriptCanvasTestFixture.h | 12 +- .../Code/Source/ScriptCanvasTestBus.cpp | 81 + .../Code/Source/ScriptCanvasTestBus.h | 21 + .../ScriptCanvasTestingSystemComponent.cpp | 6 +- .../Tests/ScriptCanvas_RuntimeInterpreted.cpp | 15 + 46 files changed, 12331 insertions(+), 266 deletions(-) create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionCycle10.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionOutPerformance.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunction.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunctionNotPure.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfNotPureUserFunction.scriptcanvas create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfPureUserFunction.scriptcanvas diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp index 0a0c3f3712..ab59ddd840 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp @@ -394,11 +394,13 @@ namespace ScriptCanvasBuilder int GetBuilderVersion() { + // #functions2 remove-execution-out-hash include version from all library nodes, split fingerprint generation to relax Is Out of Data restriction when graphs only need a recompile return static_cast(BuilderVersion::Current) + static_cast(ScriptCanvas::GrammarVersion::Current) + static_cast(ScriptCanvas::RuntimeVersion::Current) ; } + AZ::Outcome < AZ::Data::Asset, AZStd::string> LoadEditorAsset(AZStd::string_view filePath) { AZStd::shared_ptr assetDataStream = AZStd::make_shared(); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.cpp index 6d36236906..e1d02c2792 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/FunctionNodePaletteTreeItemTypes.cpp @@ -41,11 +41,11 @@ namespace ScriptCanvasEditor if (AZ::SerializeContext* serializeContext = azrtti_cast(reflectContext)) { serializeContext->Class() - ->Version(4) + ->Version(5) ->Field("AssetId", &CreateFunctionMimeEvent::m_assetId) + ->Field("sourceId", &CreateFunctionMimeEvent::m_sourceId) ; } - } CreateFunctionMimeEvent::CreateFunctionMimeEvent(const AZ::Data::AssetId& assetId, const AZ::Data::AssetType& assetType, const ScriptCanvas::Grammar::FunctionSourceId& sourceId) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja index 7b873e1362..27498a2aec 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvasNodeable_Source.jinja @@ -158,7 +158,7 @@ return {{returnNames[0]}}; {% endfor %} {# ExecutionOuts #} // ExecutionOuts begin -{{ nodemacro.ExecutionOutDefinitions(Class, attribute_QualifiedName )}} +{{ nodemacro.ExecutionOutDefinitions(Class, attribute_QualifiedName)}} // ExecutionOuts end {# Reflect #} void {{attribute_QualifiedName}}::Reflect(AZ::ReflectContext* context) 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 f66765004c..6cd0edd68c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/AutoGen/ScriptCanvas_Nodeable_Macros.jinja @@ -307,41 +307,49 @@ AZStd::tuple<{{returns|join(", ")}}> {% for executionOut in Class.findall('Output') %} {{ ExecutionOutDeclaration(Class, executionOut) }} {%- endfor %} +size_t GetRequiredOutCount() const override; {% endmacro %} -{% macro ExecutionBranchDefinition(Class, qualifiedName, executionOut) %} +{% macro ExecutionBranchDefinition(Class, qualifiedName, executionOut, outIndexBranch) %} {% set outName = CleanName(executionOut.attrib['Name']) %} {% set returns = executionOut.findall('Parameter') %} {% set params = executionOut.findall('Return') %} -void {{qualifiedName}}::Call{{CleanName(outName)}}({{ExecutionOutReturnDefinition(returns)}}{{ExecutionOutParameterDefinition(returns, params)}}) { +void {{qualifiedName}}::Call{{outName}}({{ExecutionOutReturnDefinition(returns)}}{{ExecutionOutParameterDefinition(returns, params)}}) { {% if returns|length() == 0 %} - ExecutionOut(AZ_CRC_CE("{{ executionOut.attrib['Name'] }}"){% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}} {% endfor %} + ExecutionOut({{ outIndexBranch }}{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}}{% endfor %} {% else %} - OutResult(AZ_CRC_CE("{{ executionOut.attrib['Name'] }}"), result{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}} {% endfor %} -{% endif -%}); + ExecutionOutResult({{ outIndexBranch }}, result{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}}{% endfor %} +{% endif -%}); // {{ executionOut.attrib['Name'] }} } {% endmacro %} -{% macro ExecutionOutDefinition(Class, qualifiedName, executionOut) %} +{% macro ExecutionOutDefinition(Class, qualifiedName, executionOut, outIndexLatent) %} {% set outName = CleanName(executionOut.attrib['Name']) %} {% set returns = executionOut.findall('Return') %} {% set params = executionOut.findall('Parameter') %} void {{qualifiedName}}::Call{{CleanName(outName)}}({{ExecutionOutReturnDefinition(returns)}}{{ExecutionOutParameterDefinition(returns, params)}}) { {% if returns|length() == 0 %} - ExecutionOut(AZ_CRC_CE("{{ executionOut.attrib['Name'] }}"){% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}} {% endfor %} + ExecutionOut({{ outIndexLatent }}{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}}{% endfor %} {% else %} - OutResult(AZ_CRC_CE("{{ executionOut.attrib['Name'] }}"), result{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}} {% endfor %} -{% endif -%} ); + ExecutionOutResult({{ outIndexLatent }}, result{% for parameter in params %}, {{CleanName(parameter.attrib['Name'])}}{% endfor %} +{% endif -%}); // {{ executionOut.attrib['Name'] }} } {% endmacro %} {% macro ExecutionOutDefinitions(Class, qualifiedName) %} +{% set branches = [] %} {% for method in Class.findall('Input') %} {%- for branch in method.findall('Branch') %} - {{ ExecutionBranchDefinition(Class, qualifiedName, branch) }} +{% if branches.append(branch) %}{% endif %} {%- endfor %} -{% endfor %} -{%- for executionOut in Class.findall('Output') -%} - {{ ExecutionOutDefinition(Class, qualifiedName, executionOut) }} +{% endfor %} +{%- for branch in branches -%} + {{ ExecutionBranchDefinition(Class, qualifiedName, branch, loop.index0) }} +{%- endfor %} +{%- 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 %} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/EBusHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/EBusHandler.cpp index 84e67c1215..804bb59e56 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/EBusHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/EBusHandler.cpp @@ -88,17 +88,7 @@ namespace ScriptCanvas void EBusHandler::InitializeEBusHandling(AZStd::string_view busName, AZ::BehaviorContext* behaviorContext) { CreateHandler(busName, behaviorContext); - - const AZ::BehaviorEBusHandler::EventArray& events = m_handler->GetEvents(); - AZStd::vector eventKeys; - eventKeys.reserve(events.size()); - - for (int eventIndex(0); eventIndex < events.size(); ++eventIndex) - { - eventKeys.push_back(eventIndex); - } - - InitializeExecutionOuts(eventKeys); + InitializeExecutionOuts(m_handler->GetEvents().size()); } bool EBusHandler::IsConnected() const @@ -137,7 +127,7 @@ namespace ScriptCanvas void EBusHandler::OnEvent(const char* /*eventName*/, const int eventIndex, AZ::BehaviorValueParameter* result, const int numParameters, AZ::BehaviorValueParameter* parameters) { - CallOut(AZ::Crc32(eventIndex), result, parameters, numParameters); + CallOut(eventIndex, result, parameters, numParameters); } void EBusHandler::Reflect(AZ::ReflectContext* reflectContext) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 23def4cb55..4a936c8824 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -3155,6 +3155,11 @@ namespace ScriptCanvas return {}; } + AZStd::optional Node::GetEventIndex([[maybe_unused]] AZStd::string eventName) const + { + return AZStd::nullopt; + } + AZStd::vector Node::GetEventSlotIds() const { return {}; @@ -3404,6 +3409,45 @@ namespace ScriptCanvas return GetSlotByName("True"); } + size_t Node::GetOutIndex(const Slot& slot) const + { + size_t index = 0; + auto slotId = slot.GetId(); + + if (auto map = GetSlotExecutionMap()) + { + auto& ins = map->GetIns(); + for (auto& in : ins) + { + for (auto& out : in.outs) + { + // only count branches + if (in.outs.size() > 1) + { + if (out.slotId == slotId) + { + return index; + } + + ++index; + } + } + } + + for (auto& latent : map->GetLatents()) + { + if (latent.slotId == slotId) + { + return index; + } + + ++index; + } + } + + return std::numeric_limits::max(); + } + AZ::Outcome Node::GetInternalOutKey(const Slot& slot) const { if (auto map = GetSlotExecutionMap()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index d51667764f..d3d36ae71b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -700,6 +700,8 @@ namespace ScriptCanvas // override if necessary, usually only when the node's execution topology dramatically alters at edit-time in a way that is not generally parseable ConstSlotsOutcome GetSlotsInExecutionThreadByType(const Slot& executionSlot, CombinedSlotType targetSlotType, const Slot* executionChildSlot = nullptr) const; + size_t GetOutIndex(const Slot& slot) const; + // override if necessary, only used by NodeableNodes which can hide branched outs and rename them later virtual AZ::Outcome GetInternalOutKey(const Slot& slot) const; @@ -751,6 +753,8 @@ namespace ScriptCanvas virtual AZStd::string GetEBusName() const; + virtual AZStd::optional GetEventIndex(AZStd::string eventName) const; + virtual AZStd::vector GetEventSlotIds() const; virtual AZStd::vector GetNonEventSlotIds() const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index ff8779319a..b642ef3889 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -19,7 +19,7 @@ namespace NodeableOutCpp { - void NoOp(AZ::BehaviorValueParameter* /*result*/, AZ::BehaviorValueParameter* /*arguments*/, int /*numArguments*/) {} + void NoOp([[maybe_unused]] AZ::BehaviorValueParameter*, [[maybe_unused]] AZ::BehaviorValueParameter*, [[maybe_unused]] int) {} } namespace ScriptCanvas @@ -36,14 +36,14 @@ namespace ScriptCanvas {} #if !defined(RELEASE) - void Nodeable::CallOut(const AZ::Crc32 key, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const + void Nodeable::CallOut(size_t index, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const { - GetExecutionOutChecked(key)(resultBVP, argsBVPs, numArguments); + GetExecutionOutChecked(index)(resultBVP, argsBVPs, numArguments); } #else - void Nodeable::CallOut(const AZ::Crc32 key, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const + void Nodeable::CallOut(size_t index, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const { - GetExecutionOut(key)(resultBVP, argsBVPs, numArguments); + GetExecutionOut(index)(resultBVP, argsBVPs, numArguments); } #endif // !defined(RELEASE) @@ -62,11 +62,6 @@ namespace ScriptCanvas return m_executionState->GetEntityId(); } - AZ::EntityId Nodeable::GetScriptCanvasId() const - { - return m_executionState->GetScriptCanvasId(); - } - void Nodeable::Reflect(AZ::ReflectContext* reflectContext) { if (auto serializeContext = azrtti_cast(reflectContext)) @@ -77,9 +72,9 @@ namespace ScriptCanvas { editContext->Class("Nodeable", "Nodeable") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) ; } } @@ -92,71 +87,69 @@ namespace ScriptCanvas ->Constructor() ->Method("Deactivate", &Nodeable::Deactivate) ->Method("InitializeExecutionState", &Nodeable::InitializeExecutionState) + ->Method("InitializeExecutionOuts", &Nodeable::InitializeExecutionOuts) + ->Method("InitializeExecutionOutByRequiredCount", &Nodeable::InitializeExecutionOutByRequiredCount) ->Method("IsActive", &Nodeable::IsActive) ; } } - const FunctorOut& Nodeable::GetExecutionOut(AZ::Crc32 key) const + const FunctorOut& Nodeable::GetExecutionOut(size_t index) const { - auto iter = m_outs.find(key); - AZ_Assert(iter != m_outs.end(), "no out registered for key: %d", key); - AZ_Assert(iter->second, "null execution methods are not allowed, key: %d", key); - return iter->second; + AZ_Assert(index < m_outs.size(), "index out of range in Nodeable::m_outs"); + auto& iter = m_outs[index]; + AZ_Assert(iter, "null execution methods are not allowed, index: %zu", index); + return iter; } - const FunctorOut& Nodeable::GetExecutionOutChecked(AZ::Crc32 key) const + const FunctorOut& Nodeable::GetExecutionOutChecked(size_t index) const { - auto iter = m_outs.find(key); - - if (iter == m_outs.end()) - { - return m_noOpFunctor; - } - else if (!iter->second) + + if (index >= m_outs.size() && m_outs[index]) { return m_noOpFunctor; } - return iter->second; + return m_outs[index]; } - void Nodeable::InitializeExecutionState(ExecutionState* executionState) + AZ::EntityId Nodeable::GetScriptCanvasId() const { - AZ_Assert(executionState != nullptr, "execution state for nodeable must not be nullptr"); - AZ_Assert(m_executionState == nullptr, "execution state already initialized"); - m_executionState = executionState->WeakFromThis(); + return m_executionState->GetScriptCanvasId(); } - void Nodeable::InitializeExecutionOuts(const AZ::Crc32* begin, const AZ::Crc32* end) + void Nodeable::InitializeExecutionOuts(size_t count) { - m_outs.reserve(end - begin); + m_outs.resize(count, m_noOpFunctor); + } - for (; begin != end; ++begin) - { - SetExecutionOut(*begin, AZStd::move(FunctorOut(&NodeableOutCpp::NoOp))); - } + void Nodeable::InitializeExecutionOutByRequiredCount() + { + InitializeExecutionOuts(GetRequiredOutCount()); } - void Nodeable::InitializeExecutionOuts(const AZStd::vector& keys) + void Nodeable::InitializeExecutionState(ExecutionState* executionState) { - InitializeExecutionOuts(keys.begin(), keys.end()); + AZ_Assert(executionState != nullptr, "execution state for nodeable must not be nullptr"); + AZ_Assert(m_executionState == nullptr, "execution state already initialized"); + m_executionState = executionState->WeakFromThis(); + OnInitializeExecutionState(); } - void Nodeable::SetExecutionOut(AZ::Crc32 key, FunctorOut&& out) + void Nodeable::SetExecutionOut(size_t index, FunctorOut&& out) { - AZ_Assert(out, "null executions methods are not allowed, key: %d", key); - m_outs[key] = AZStd::move(out); + AZ_Assert(out, "null executions methods are not allowed, index: %zu", index); + m_outs[index] = AZStd::move(out); } - void Nodeable::SetExecutionOutChecked(AZ::Crc32 key, FunctorOut&& out) + void Nodeable::SetExecutionOutChecked(size_t index, FunctorOut&& out) { if (!out) { - AZ_Error("ScriptCanvas", false, "null executions methods are not allowed, key: %d", key); + AZ_Error("ScriptCanvas", false, "null executions methods are not allowed, index: %zu", index); return; } - SetExecutionOut(key, AZStd::move(out)); + SetExecutionOut(index, AZStd::move(out)); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.h index 3695f3e9fa..963893ee3f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.h @@ -29,6 +29,23 @@ namespace ScriptCanvas class SubgraphInterface; } + /* + Note: Many parts of AzAutoGen, compilation, and runtime depend on the order of declaration and addition of slots. + The display order can be manipulated in the editor, but it will always just be a change of view. + + Whenever in doubt, this is the order, in pseudo code + + for in : Ins do + somethingOrdered(in) + for branch : in.Branches do + somethingOrdered(branch) + end + end + for out : Outs do + somethingOrdered(out) + end + */ + // derive from this to make an object that when wrapped with a NodeableNode can be instantly turned into a node that is easily embedded in graphs, // and easily compiled in class Nodeable @@ -40,21 +57,23 @@ namespace ScriptCanvas // reflect nodeable class API static void Reflect(AZ::ReflectContext* reflectContext); + // the run-time constructor for non-EBus handlers Nodeable(); + // this constructor is used by EBus handlers only Nodeable(ExecutionStateWeakPtr executionState); virtual ~Nodeable() = default; - void CallOut(const AZ::Crc32 key, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const; + void CallOut(size_t index, AZ::BehaviorValueParameter* resultBVP, AZ::BehaviorValueParameter* argsBVPs, int numArguments) const; AZ::Data::AssetId GetAssetId() const; AZ::EntityId GetEntityId() const; - const Execution::FunctorOut& GetExecutionOut(AZ::Crc32 key) const; + const Execution::FunctorOut& GetExecutionOut(size_t index) const; - const Execution::FunctorOut& GetExecutionOutChecked(AZ::Crc32 key) const; + const Execution::FunctorOut& GetExecutionOutChecked(size_t index) const; virtual NodePropertyInterface* GetPropertyInterface(AZ::Crc32 /*propertyId*/) { return nullptr; } @@ -66,98 +85,97 @@ namespace ScriptCanvas // any would only be good if graphs could opt into it, and execution slots could annotate changing activity level virtual bool IsActive() const { return false; } - void InitializeExecutionOuts(const AZ::Crc32* begin, const AZ::Crc32* end); - - void InitializeExecutionOuts(const AZStd::vector& keys); + void InitializeExecutionOuts(size_t count); - void SetExecutionOut(AZ::Crc32 key, Execution::FunctorOut&& out); + void SetExecutionOut(size_t index, Execution::FunctorOut&& out); - void SetExecutionOutChecked(AZ::Crc32 key, Execution::FunctorOut&& out); + void SetExecutionOutChecked(size_t index, Execution::FunctorOut&& out); protected: + void InitializeExecutionOutByRequiredCount(); + void InitializeExecutionState(ExecutionState* executionState); + virtual void OnInitializeExecutionState() {} + virtual void OnDeactivate() {} + virtual size_t GetRequiredOutCount() const { return 0; } + + // Required to decay array type to pointer type + template + using decay_array = AZStd::conditional_t>, std::remove_extent_t>*, T&&>; + // all of these hooks are known at compile time, so no branching - // we will need with and without result calls for each time for method + // we will need with and without result calls for each type of method // methods with result but no result requested, etc + template + void ExecutionOut(size_t index, t_Args&&... args) const + { + // it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) + AZStd::tuple...> lvalueWrapper(AZStd::forward(args)...); + using BVPReserveArray = AZStd::array; + auto MakeBVPArrayFunction = [](auto&&... element) + { + return BVPReserveArray{ {AZ::BehaviorValueParameter{&element}...} }; + }; + + BVPReserveArray argsBVPs = AZStd::apply(MakeBVPArrayFunction, lvalueWrapper); + CallOut(index, nullptr, argsBVPs.data(), sizeof...(t_Args)); + } + + void ExecutionOut(size_t index) const + { + // it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) + CallOut(index, nullptr, nullptr, 0); + } template - void OutResult(const AZ::Crc32 key, t_Return& result) const + void ExecutionOutResult(size_t index, t_Return& result) const { - // this is correct, it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) + // It is up to the FunctorOut referenced by the index to decide what to do with these params (whether to modify or handle strings differently) AZ::BehaviorValueParameter resultBVP(&result); - - CallOut(key, &resultBVP, nullptr, 0); + CallOut(index, &resultBVP, nullptr, 0); #if !defined(RELEASE) if (!resultBVP.GetAsUnsafe()) { - AZ_Error("ScriptCanvas", false, "%s:CallOut(%u) failed to provide a useable result", TYPEINFO_Name(), (AZ::u32)key); + AZ_Error("ScriptCanvas", false, "%s:CallOut(%zu) failed to provide a useable result", TYPEINFO_Name(), index); return; } #endif result = *resultBVP.GetAsUnsafe(); } - // Required to decay array type to pointer type - template - using decay_array = AZStd::conditional_t>, std::remove_extent_t>*, T&&>; - template - void OutResult(const AZ::Crc32 key, t_Return& result, t_Args&&... args) const + void ExecutionOutResult(size_t index, t_Return& result, t_Args&&... args) const { - // this is correct, it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) + // it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) AZStd::tuple...> lvalueWrapper(AZStd::forward(args)...); using BVPReserveArray = AZStd::array; auto MakeBVPArrayFunction = [](auto&&... element) { return BVPReserveArray{ {AZ::BehaviorValueParameter{&element}...} }; }; + BVPReserveArray argsBVPs = AZStd::apply(MakeBVPArrayFunction, lvalueWrapper); AZ::BehaviorValueParameter resultBVP(&result); - - CallOut(key, &resultBVP, argsBVPs.data(), sizeof...(t_Args)); + CallOut(index, &resultBVP, argsBVPs.data(), sizeof...(t_Args)); #if !defined(RELEASE) if (!resultBVP.GetAsUnsafe()) { - AZ_Error("ScriptCanvas", false, "%s:CallOut(%u) failed to provide a useable result", TYPEINFO_Name(), (AZ::u32)key); + AZ_Error("ScriptCanvas", false, "%s:CallOut(%zu) failed to provide a useable result", TYPEINFO_Name(), index); return; } #endif result = *resultBVP.GetAsUnsafe(); } - template - void ExecutionOut(const AZ::Crc32 key, t_Args&&... args) const - { - // this is correct, it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) - AZStd::tuple...> lvalueWrapper(AZStd::forward(args)...); - using BVPReserveArray = AZStd::array; - auto MakeBVPArrayFunction = [](auto&&... element) - { - return BVPReserveArray{ {AZ::BehaviorValueParameter{&element}...} }; - }; - BVPReserveArray argsBVPs = AZStd::apply(MakeBVPArrayFunction, lvalueWrapper); - - CallOut(key, nullptr, argsBVPs.data(), sizeof...(t_Args)); - } - - void ExecutionOut(const AZ::Crc32 key) const - { - // this is correct, it is up to the FunctorOut referenced by key to decide what to do with these params (whether to modify or handle strings differently) - CallOut(key, nullptr, nullptr, 0); - } - private: - // keep this here, and don't even think about putting it back in the FunctorOuts by any method*, lambda capture or other. - // programmers will need this for internal node state debugging and who knows what other reasons - // * Lua execution is an exception ExecutionStateWeakPtr m_executionState = nullptr; Execution::FunctorOut m_noOpFunctor; - AZStd::unordered_map m_outs; + AZStd::vector m_outs; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp index 8fc582954a..c406a5c100 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp @@ -91,19 +91,6 @@ namespace ScriptCanvas AZ_Error("ScriptCanvas", m_nodeable, "null Nodeable in NodeableNode::ConfigureSlots"); } - AZ::Outcome> NodeableNode::FindMethodAndInputIndexOfSlot(const SlotId& slotID) const - { - if (auto thisSlot = GetSlot(slotID)) - { - if (thisSlot->GetType() == CombinedSlotType::DataIn) - { - return m_slotExecutionMap.FindInAndInputIndexOfSlot(slotID); - } - } - - return AZ::Failure(); - } - AZ::Outcome NodeableNode::GetBehaviorContextClass() const { AZ::BehaviorContext* behaviorContext = NodeableNodeCpp::GetBehaviorContext(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h index 60ad7d3273..0193641d97 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.h @@ -73,8 +73,6 @@ namespace ScriptCanvas void ConfigureSlots() override; - AZ::Outcome> FindMethodAndInputIndexOfSlot(const SlotId& slotID) const; - AZ::Outcome GetBehaviorContextClass() const; ConstSlotsOutcome GetBehaviorContextOutName(const Slot& inSlot) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.cpp index 34af917c96..05c5e0e5d7 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.cpp @@ -152,22 +152,6 @@ namespace ScriptCanvas return nullptr; } - AZ::Outcome> Map::FindInAndInputIndexOfSlot(const SlotId& slotID) const - { - for (const auto& in : m_ins) - { - auto inputIter = find_if(in.inputs, [&slotID](const Input& input) { return input.slotId == slotID; }); - if (inputIter != in.inputs.end()) - { - const size_t inIndex = &in - m_ins.begin(); - const size_t inputIndex = inputIter - in.inputs.begin(); - return AZ::Success(AZStd::make_pair(inIndex, inputIndex)); - } - } - - return AZ::Failure(); - } - const In* Map::FindInFromInputSlot(const SlotId& slotID) const { auto iter = find_if diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.h index 25c237b138..9daf1d8eb9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SlotExecutionMap.h @@ -124,8 +124,6 @@ namespace ScriptCanvas Map(Outs&& latents); - AZ::Outcome> FindInAndInputIndexOfSlot(const SlotId& slotID) const; - const In* FindInFromInputSlot(const SlotId& slotID) const; SlotId FindInputSlotIdBySource(VariableId inputSourceId, Grammar::FunctionSourceId inSourceId) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp index 61ea74d011..e73c049780 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp @@ -209,13 +209,18 @@ namespace ScriptCanvas m_latents.push_back(out); } - void SubgraphInterface::AddOutKey(const AZStd::string& name) + bool SubgraphInterface::AddOutKey(const AZStd::string& name) { const AZ::Crc32 key(name); if (AZStd::find(m_outKeys.begin(), m_outKeys.end(), key) == m_outKeys.end()) { m_outKeys.push_back(key); + return true; + } + else + { + return false; } } @@ -708,7 +713,7 @@ namespace ScriptCanvas } // Populates the list of out keys - void SubgraphInterface::Parse() + AZ::Outcome SubgraphInterface::Parse() { m_outKeys.clear(); @@ -716,14 +721,22 @@ namespace ScriptCanvas { for (const auto& out : in.outs) { - AddOutKey(out.displayName); + if (!AddOutKey(out.displayName)) + { + return AZ::Failure(AZStd::string::format("Out %s was already in the list: %s", out.displayName.c_str())); + } } } for (const auto& latent : m_latents) { - AddOutKey(latent.displayName); + if (!AddOutKey(latent.displayName)) + { + return AZ::Failure(AZStd::string::format("Out %s was already in the list: %s", latent.displayName.c_str())); + } } + + return AZ::Success(); } void SubgraphInterface::Reflect(AZ::ReflectContext* refectContext) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h index 3eea850666..069f3c84a2 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h @@ -232,7 +232,7 @@ namespace ScriptCanvas bool operator==(const SubgraphInterface& rhs) const; // Populates the list of out keys - void Parse(); + AZ::Outcome Parse(); bool RequiresConstructionParameters() const; @@ -266,7 +266,7 @@ namespace ScriptCanvas AZStd::vector m_outKeys; NamespacePath m_namespacePath; - void AddOutKey(const AZStd::string& name); + bool AddOutKey(const AZStd::string& name); const Out* FindImmediateOut(const AZStd::string& in, const AZStd::string& out) const; const In* FindIn(const AZStd::string& inSlotId) const; const Out* FindLatentOut(const AZStd::string& latent) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index 722328ff17..518174d0f8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -508,11 +508,10 @@ namespace ScriptCanvas const int argsCount = lua_gettop(lua); AZ_Assert(argsCount >= 2, "CallExecutionOut: Error in compiled Lua file, not enough arguments"); AZ_Assert(lua_isuserdata(lua, 1), "CallExecutionOut: Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); + AZ_Assert(lua_isnumber(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a number"); Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, 1); - const char* keyStr = AZ::ScriptValue::StackRead(lua, 2); - AZ_Assert(keyStr, "CallExecutionOut: Failed to read key string"); - nodeable->CallOut(AZ::Crc32(keyStr), nullptr, nullptr, argsCount - 2); + size_t index = aznumeric_caster(lua_tointeger(lua, -2)); + nodeable->CallOut(index, nullptr, nullptr, argsCount - 2); // Lua: results... return lua_gettop(lua); } @@ -559,23 +558,14 @@ namespace ScriptCanvas int InitializeNodeableOutKeys(lua_State* lua) { using namespace ExecutionInterpretedAPICpp; - // Lua: usernodeable, outKeys... + // Lua: usernodeable, keyCount const int argsCount = lua_gettop(lua); - AZ_Assert(argsCount >= 2, "InitializeNodeableOutKeys: Error in compiled Lua file, not enough arguments"); - AZ_Assert((argsCount - 1) < k_MaxNodeableOuts, "InitializeNodeableOutKeys: Error in compiled Lua file, too many outs for nodeable out)"); + AZ_Assert(argsCount == 2, "InitializeNodeableOutKeys: Error in compiled Lua file, not enough arguments"); AZ_Assert(lua_isuserdata(lua, 1), "InitializeNodeableOutKeys: Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, 1); - const int keyCount = argsCount - 1; - - AZStd::array keys; - - for (int argumentIndex = 2, sentinel = argsCount + 1; argumentIndex != sentinel; ++argumentIndex) - { - AZ_Assert(lua_isnumber(lua, argumentIndex), "InitializeNodeableOutKeys: Error in compiled lua file, argument at Lua index #%d was not an integer", argumentIndex); - keys[argumentIndex - 2] = static_cast(lua_tointeger(lua, argumentIndex)); - } - - nodeable->InitializeExecutionOuts(keys.begin(), keys.begin() + keyCount); + AZ_Assert(lua_isnumber(lua, 2), "InitializeNodeableOutKeys: Error in compiled lua file, 2nd argument was not an integer"); + const size_t keyCount = aznumeric_caster(lua_tointeger(lua, 2)); + nodeable->InitializeExecutionOuts(keyCount); return 0; } @@ -595,19 +585,18 @@ namespace ScriptCanvas // \see https://jira.agscollab.com/browse/LY-99750 AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); + AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a number"); AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)"); Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, -3); AZ_Assert(nodeable, "Failed to read nodeable"); - const char* keyStr = AZ::ScriptValue::StackRead(lua, -2); - AZ_Assert(keyStr, "Failed to read key string"); - // Lua: nodeable, string, lambda + size_t index = aznumeric_caster(lua_tointeger(lua, -2)); + // Lua: nodeable, index, lambda lua_pushvalue(lua, -1); - // Lua: nodeable, string, lambda, lambda + // Lua: nodeable, index, lambda, lambda - nodeable->SetExecutionOut(AZ::Crc32(keyStr), OutInterpreted(lua)); - // Lua: nodeable, string, lambda + nodeable->SetExecutionOut(index, OutInterpreted(lua)); + // Lua: nodeable, index, lambda // \todo clear these immediately after they are not needed with an explicit call written by the translator return 0; @@ -618,20 +607,19 @@ namespace ScriptCanvas // \note Return values could become necessary. // \see https://jira.agscollab.com/browse/LY-99750 - AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); - AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)"); + AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOutResult is not userdata (Nodeable)"); + AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOutResult is not a number"); + AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOutResult is not a function (lambda need to get around atypically routed arguments)"); Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, -3); // this won't be a BCO, because BCOs won't be necessary in the interpreted mode...most likely AZ_Assert(nodeable, "Failed to read nodeable"); - const char* keyStr = AZ::ScriptValue::StackRead(lua, -2); - AZ_Assert(keyStr, "Failed to read key string"); - // Lua: nodeable, string, lambda + size_t index = aznumeric_caster(lua_tointeger(lua, -2)); + // Lua: nodeable, index, lambda lua_pushvalue(lua, -1); - // Lua: nodeable, string, lambda, lambda + // Lua: nodeable, index, lambda, lambda - nodeable->SetExecutionOut(AZ::Crc32(keyStr), OutInterpretedResult(lua)); - // Lua: nodeable, string, lambda + nodeable->SetExecutionOut(index, OutInterpretedResult(lua)); + // Lua: nodeable, index, lambda // \todo clear these immediately after they are not needed with an explicit call written by the translator return 0; @@ -639,20 +627,19 @@ namespace ScriptCanvas int SetExecutionOutUserSubgraph(lua_State* lua) { - AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); - AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)"); + AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOutUserSubgraph is not userdata (Nodeable)"); + AZ_Assert(lua_isnumber(lua, -2), "Error in compiled lua file, 2nd argument to SetExecutionOutUserSubgraph is not a number"); + AZ_Assert(lua_isfunction(lua, -1), "Error in compiled lua file, 3rd argument to SetExecutionOutUserSubgraph is not a function (lambda need to get around atypically routed arguments)"); Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, -3); AZ_Assert(nodeable, "Failed to read nodeable"); - const char* keyStr = AZ::ScriptValue::StackRead(lua, -2); - AZ_Assert(keyStr, "Failed to read key string"); - // Lua: nodeable, string, lambda + size_t index = aznumeric_caster(lua_tointeger(lua, -2)); + // Lua: nodeable, index, lambda lua_pushvalue(lua, -1); - // Lua: nodeable, string, lambda, lambda + // Lua: nodeable, index, lambda, lambda - nodeable->SetExecutionOut(AZ::Crc32(keyStr), OutInterpretedUserSubgraph(lua)); - // Lua: nodeable, string, lambda + nodeable->SetExecutionOut(index, OutInterpretedUserSubgraph(lua)); + // Lua: nodeable, index, lambda // \todo clear these immediately after they are not needed with an explicit call written by the translator return 0; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp index 6612039c65..72b787213b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedEBusAPI.cpp @@ -83,7 +83,7 @@ namespace ScriptCanvas int EBusHandlerCreateAndConnectTo(lua_State* lua) { - // Lua: executionState, (event name) string, (address aztypeid) string, (address) ? + // Lua: executionState, (ebus name) string, (address aztypeid) string, (address) ? auto executionState = AZ::ScriptValue::StackRead(lua, 1); auto ebusName = AZ::ScriptValue::StackRead(lua, 2); EBusHandler* ebusHandler = aznew EBusHandler(executionState->WeakFromThis(), ebusName, AZ::ScriptContext::FromNativeContext(lua)->GetBoundContext()); @@ -96,7 +96,7 @@ namespace ScriptCanvas ebusHandler->ConnectTo(address); AZ::Internal::LuaClassToStack(lua, ebusHandler, azrtti_typeid(), AZ::ObjectToLua::ByReference, AZ::AcquisitionOnPush::ScriptAcquire); - // Lua: executionState, (event name) string, (address aztypeid) string, (address) ?, handler + // Lua: executionState, (ebus name) string, (address aztypeid) string, (address) ?, handler return 1; } @@ -114,27 +114,23 @@ namespace ScriptCanvas const int k_eventNameIndex = -2; const int k_lambdaIndex = -1; - AZ_Assert(lua_isuserdata(lua, k_nodeableIndex), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, k_eventNameIndex), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); - AZ_Assert(lua_isfunction(lua, k_lambdaIndex), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)"); + AZ_Assert(lua_isuserdata(lua, k_nodeableIndex), "Error in compiled lua file, 1st argument to EBusHandlerHandleEvent is not userdata (EBusHandler)"); + AZ_Assert(lua_isnumber(lua, k_eventNameIndex), "Error in compiled lua file, 2nd argument to EBusHandlerHandleEvent is not a number"); + AZ_Assert(lua_isfunction(lua, k_lambdaIndex), "Error in compiled lua file, 3rd argument to EBusHandlerHandleEvent is not a function"); - auto nodeable = AZ::ScriptValue::StackRead(lua, k_nodeableIndex); // this won't be a BCO, because BCOs won't be necessary in the interpreted mode...most likely + auto nodeable = AZ::ScriptValue::StackRead(lua, k_nodeableIndex); AZ_Assert(nodeable, "Failed to read EBusHandler"); - const char* keyStr = lua_tostring(lua, k_eventNameIndex); - AZ_Assert(keyStr, "Failed to read key string"); - const int eventIndex = nodeable->GetEventIndex(keyStr); - AZ_Assert(eventIndex != -1, "Event index was not found for %s-%s", nodeable->GetEBusName().data(), keyStr); + const int eventIndex = lua_tointeger(lua, k_eventNameIndex); + AZ_Assert(eventIndex != -1, "Event index was not found for %s", nodeable->GetEBusName().data()); // install the generic hook for the event nodeable->HandleEvent(eventIndex); // Lua: nodeable, string, lambda - lua_pushvalue(lua, k_lambdaIndex); // Lua: nodeable, string, lambda, lambda // route the event handling to the lambda on the top of the stack nodeable->SetExecutionOut(AZ::Crc32(eventIndex), OutInterpreted(lua)); // Lua: nodeable, string, lambda - return 0; } @@ -145,16 +141,14 @@ namespace ScriptCanvas const int k_eventNameIndex = -2; const int k_lambdaIndex = -1; - AZ_Assert(lua_isuserdata(lua, k_nodeableIndex), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); - AZ_Assert(lua_isstring(lua, k_eventNameIndex), "Error in compiled lua file, 2nd argument to SetExecutionOut is not a string (Crc key)"); - AZ_Assert(lua_isfunction(lua, k_lambdaIndex), "Error in compiled lua file, 3rd argument to SetExecutionOut is not a function (lambda need to get around atypically routed arguments)"); + AZ_Assert(lua_isuserdata(lua, k_nodeableIndex), "Error in compiled lua file, 1st argument to EBusHandlerHandleEventResult is not userdata (EBusHandler)"); + AZ_Assert(lua_isnumber(lua, k_eventNameIndex), "Error in compiled lua file, 2nd argument to EBusHandlerHandleEventResult is not a number"); + AZ_Assert(lua_isfunction(lua, k_lambdaIndex), "Error in compiled lua file, 3rd argument to EBusHandlerHandleEventResult is not a function"); - auto nodeable = AZ::ScriptValue::StackRead(lua, k_nodeableIndex); // this won't be a BCO, because BCOs won't be necessary in the interpreted mode...most likely + auto nodeable = AZ::ScriptValue::StackRead(lua, k_nodeableIndex); AZ_Assert(nodeable, "Failed to read EBusHandler"); - const char* keyStr = lua_tostring(lua, k_eventNameIndex); - AZ_Assert(keyStr, "Failed to read key string"); - const int eventIndex = nodeable->GetEventIndex(keyStr); - AZ_Assert(eventIndex != -1, "Event index was not found for %s-%s", nodeable->GetEBusName().data(), keyStr); + const int eventIndex = lua_tointeger(lua, k_eventNameIndex); + AZ_Assert(eventIndex != -1, "Event index was not found for %s", nodeable->GetEBusName().data()); // install the generic hook for the event nodeable->HandleEvent(eventIndex); // Lua: nodeable, string, lambda @@ -165,7 +159,6 @@ namespace ScriptCanvas // route the event handling to the lambda on the top of the stack nodeable->SetExecutionOut(AZ::Crc32(eventIndex), OutInterpretedResult(lua)); // Lua: nodeable, string, lambda - return 0; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp index dbcaad635b..ba1d34fea0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp @@ -70,7 +70,7 @@ namespace ScriptCanvas void RuntimeComponent::Execute() { - AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::InitializeExecution (%s)", m_runtimeAsset.GetId().ToString().c_str()); + AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::Execute (%s)", m_runtimeAsset.GetId().ToString().c_str()); AZ_Assert(m_executionState, "RuntimeComponent::Execute called without an execution state"); SC_EXECUTION_TRACE_GRAPH_ACTIVATED(CreateActivationInfo()); SCRIPT_CANVAS_PERFORMANCE_SCOPE_EXECUTION(m_executionState->GetScriptCanvasId(), m_runtimeAsset.GetId()); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 8f7fa2263e..958e37f82c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -434,7 +434,7 @@ namespace ScriptCanvas if (!root->HasExplicitUserOutCalls()) { - // there is a single out call, default or not + // there is a single out, default or not Out out; if (outCalls.empty()) @@ -468,9 +468,7 @@ namespace ScriptCanvas } else { - // for now, all outs must return all the same output, - // if the UI changes, we'll need to track the output of each individual output - if (outCalls.empty()) + if (outCalls.size() < 2) { AddError(root->GetNodeId(), root, ScriptCanvas::ParseErrors::NotEnoughBranchesForReturn); return; @@ -503,6 +501,9 @@ namespace ScriptCanvas , returnValueVariable->m_sourceVariableId }); } + AZStd::const_pointer_cast(outCall)->SetOutCallIndex(m_outIndexCount); + ++m_outIndexCount; + in.outs.push_back(AZStd::move(out)); } } @@ -543,6 +544,8 @@ namespace ScriptCanvas , returnValueVariable->m_sourceVariableId }); } + AZStd::const_pointer_cast(outCall)->SetOutCallIndex(m_outIndexCount); + ++m_outIndexCount; m_subgraphInterface.AddLatent(AZStd::move(out)); } @@ -908,6 +911,7 @@ namespace ScriptCanvas ebusHandling->m_startingAdress = startingAddress; } + ebusHandling->m_node = &node; m_ebusHandlingByNode.emplace(&node, ebusHandling); return true; } @@ -3252,6 +3256,15 @@ namespace ScriptCanvas AZ_Assert(childOutSlot, "null slot in child out slot list"); ExecutionTreePtr internalOut = OpenScope(child, node, childOutSlot); internalOut->SetNodeable(execution->GetNodeable()); + + const size_t outIndex = node->GetOutIndex(*childOutSlot); + if (outIndex == std::numeric_limits::max()) + { + AddError(execution, aznew Internal::ParseError(node->GetEntityId(), AZStd::string::format("Missing internal out key for slot %s", childOutSlot->GetName().c_str()))); + return; + } + + internalOut->SetOutCallIndex(outIndex); internalOut->MarkInternalOut(); internalOut->SetSymbol(Symbol::FunctionDefinition); auto outNameOutcome = node->GetInternalOutKey(*childOutSlot); @@ -3893,6 +3906,14 @@ namespace ScriptCanvas auto latentOutKeyOutcome = node.GetLatentOutKey(*slot); if (latentOutKeyOutcome.IsSuccess()) { + const size_t outIndex = node.GetOutIndex(*slot); + if (outIndex == std::numeric_limits::max()) + { + AddError(outRoot, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format("Missing internal out key for slot %s", slot->GetName().c_str()))); + return; + } + + outRoot->SetOutCallIndex(outIndex); outRoot->SetName(latentOutKeyOutcome.GetValue().data()); AZStd::const_pointer_cast(nodeableParseIter->second)->m_latents.emplace_back(outRoot->GetName(), outRoot); } @@ -4622,7 +4643,13 @@ namespace ScriptCanvas m_userInsThatRequireTopology.clear(); ParseUserOuts(); - m_subgraphInterface.Parse(); + + auto parseOutcome = m_subgraphInterface.Parse(); + + if (!parseOutcome.IsSuccess()) + { + AddError(nullptr, aznew Internal::ParseError(AZ::EntityId(), AZStd::string::format("Subgraph interface failed to parse: %s", parseOutcome.GetError().c_str()).c_str())); + } } void AbstractCodeModel::ParseUserIn(ExecutionTreePtr root, const Nodes::Core::FunctionDefinitionNode* nodeling) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index 6eef1b6934..f1ad7b986b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -507,6 +507,7 @@ namespace ScriptCanvas static UserInParseTopologyResult ParseUserInTolopology(size_t nodelingsOutCount, size_t leavesWithoutNodelingsCount); + size_t m_outIndexCount = 0; ExecutionTreePtr m_start; AZStd::vector m_startNodes; ScopePtr m_graphScope; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp index ab467127c1..a5a98b5444 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp @@ -1057,6 +1057,13 @@ namespace ScriptCanvas && azrtti_istypeof(execution->GetId().m_node); } + bool IsUserFunctionCallPure(const ExecutionTreeConstPtr& execution) + { + return (execution->GetSymbol() == Symbol::FunctionCall) + && azrtti_istypeof(execution->GetId().m_node) + && azrtti_cast(execution->GetId().m_node)->IsPure(); + } + bool IsUserFunctionDefinition(const ExecutionTreeConstPtr& execution) { auto nodeling = azrtti_cast(execution->GetId().m_node); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h index 7bdfa39c7c..1e2d102d2d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h @@ -163,6 +163,8 @@ namespace ScriptCanvas bool IsUserFunctionCall(const ExecutionTreeConstPtr& execution); + bool IsUserFunctionCallPure(const ExecutionTreeConstPtr& execution); + bool IsUserFunctionDefinition(const ExecutionTreeConstPtr& execution); const ScriptCanvas::Nodes::Core::FunctionDefinitionNode* IsUserOutNode(const Node* node); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h index 68856325d0..c2605dce45 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.h @@ -90,11 +90,11 @@ namespace ScriptCanvas AZ_CLASS_ALLOCATOR(EBusHandling, AZ::SystemAllocator, 0); bool m_isAddressed = false; + const Node* m_node = nullptr; VariableConstPtr m_startingAdress; AZStd::string m_ebusName; AZStd::string m_handlerName; AZStd::vector> m_events; - void Clear(); }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h index 72449ebc6d..bcfcccbaca 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h @@ -110,7 +110,7 @@ namespace ScriptCanvas constexpr const char* k_InitializeStaticsName = "InitializeStatics"; constexpr const char* k_InitializeNodeableOutKeys = "InitializeNodeableOutKeys"; - + constexpr const char* k_InitializeExecutionOutByRequiredCountName = "InitializeExecutionOutByRequiredCount"; constexpr const char* k_InterpretedConfigurationPerformance = "SCRIPT_CANVAS_GLOBAL_PERFORMANCE"; constexpr const char* k_InterpretedConfigurationRelease = "SCRIPT_CANVAS_GLOBAL_RELEASE"; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index e1e46d231e..c6e7925a31 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -260,6 +260,11 @@ namespace ScriptCanvas return m_nodeable; } + AZStd::optional ExecutionTree::GetOutCallIndex() const + { + return m_outCallIndex != std::numeric_limits::max() ? AZStd::optional(m_outCallIndex) : AZStd::nullopt; + } + ExecutionTreeConstPtr ExecutionTree::GetParent() const { return m_parent; @@ -559,6 +564,11 @@ namespace ScriptCanvas m_lexicalScope = lexicalScope; } + void ExecutionTree::SetOutCallIndex(size_t index) + { + m_outCallIndex = index; + } + void ExecutionTree::SetParent(ExecutionTreePtr parent) { m_parent = parent; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h index 518b1ba7f1..f1cebde204 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h @@ -170,6 +170,8 @@ namespace ScriptCanvas VariableConstPtr GetNodeable() const; + AZStd::optional GetOutCallIndex() const; + ExecutionTreeConstPtr GetParent() const; ExecutionTreeConstPtr GetRoot() const; @@ -252,6 +254,8 @@ namespace ScriptCanvas void SetNodeable(VariableConstPtr nodeable); + void SetOutCallIndex(size_t index); + void SetParent(ExecutionTreePtr parent); void SetScope(ScopePtr scope); @@ -286,6 +290,8 @@ namespace ScriptCanvas bool m_hasExplicitUserOutCalls = false; + size_t m_outCallIndex = std::numeric_limits::max(); + // The node and the activation slot. The execution in, or the event or latent out slot. ExecutionId m_in; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp index 881d087a3d..a23575693e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Internal/Nodeables/BaseTimer.cpp @@ -66,7 +66,7 @@ namespace ScriptCanvas break; } - while (m_timerCounter > m_timerDuration) + while (m_timerCounter >= m_timerDuration) { if (!m_isActive) { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp index cd57cb6608..0fc40bceee 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.cpp @@ -393,6 +393,11 @@ namespace ScriptCanvas return false; } + AZStd::optional EBusEventHandler::GetEventIndex(AZStd::string eventName) const + { + return m_handler->GetFunctionIndex(eventName.c_str()); + } + const EBusEventEntry* EBusEventHandler::FindEvent(const AZStd::string& name) const { AZ::Crc32 key = AZ::Crc32(name.c_str()); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h index 890b50a9e4..be624d608d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/EBusEventHandler.h @@ -115,6 +115,7 @@ namespace ScriptCanvas AZ::Outcome GetFunctionCallName(const Slot* /*slot*/) const override; bool IsEBusAddressed() const override; + AZStd::optional GetEventIndex(AZStd::string eventName) const; const EBusEventEntry* FindEvent(const AZStd::string& name) const; AZStd::string GetEBusName() const override; bool IsAutoConnected() const override; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp index 962ee3e515..a7dc586a94 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp @@ -548,6 +548,11 @@ namespace ScriptCanvas return EBusEventHandlerProperty::GetDisconnectSlot(this); } + AZStd::optional ReceiveScriptEvent::GetEventIndex(AZStd::string eventName) const + { + return m_handler->GetFunctionIndex(eventName.c_str());; + } + AZStd::vector ReceiveScriptEvent::GetEventSlotIds() const { AZStd::vector eventSlotIds; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h index 3f2425cd4a..dcf1bca50e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h @@ -57,6 +57,7 @@ namespace ScriptCanvas AZ::Outcome GetInternalOutKey(const Slot& slot) const override; const Slot* GetEBusConnectSlot() const override; const Slot* GetEBusDisconnectSlot() const override; + AZStd::optional GetEventIndex(AZStd::string eventName) const override; AZStd::vector GetEventSlotIds() const override; AZStd::vector GetNonEventSlotIds() const override; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h index 157f086fca..4b4bd59dc9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Operators/Math/OperatorLerpNodeable.h @@ -136,16 +136,21 @@ namespace ScriptCanvas } protected: + size_t GetRequiredOutCount() const override + { + return 2; + } + void Lerp(float t) { const t_Operand step = m_start + (m_difference * t); // make a release note that the lerp complete and tick slot are two different execution threads - ExecutionOut(AZ_CRC_CE("Tick"), step, t); + ExecutionOut(0, step, t); if (AZ::IsClose(t, 1.0f, AZ::Constants::FloatEpsilon)) { StopLerp(); - ExecutionOut(AZ_CRC_CE("Lerp Complete")); + ExecutionOut(1); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/SystemComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/SystemComponent.h index b15ec596f9..3d5acfbee1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/SystemComponent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/SystemComponent.h @@ -100,7 +100,7 @@ namespace ScriptCanvas using LockType = AZStd::lock_guard; AZStd::unordered_map m_ownedObjectsByAddress; MutexType m_ownedObjectsByAddressMutex; - int m_infiniteLoopDetectionMaxIterations = 3000; + int m_infiniteLoopDetectionMaxIterations = 1000000; int m_maxHandlerStackDepth = 50; static void SafeRegisterPerformanceTracker(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index bd583cb43d..8f28a7f94b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -689,8 +689,16 @@ namespace ScriptCanvas void GraphToLua::TranslateExecutionTreeUserOutCall(Grammar::ExecutionTreeConstPtr execution) { - // \todo revisit with per-entity run time storage that keeps execution out calls - m_dotLua.WriteIndented("%s(self, \"%s\"", Grammar::k_NodeableCallInterpretedOut, execution->GetName().data()); + auto outCallIndexOptional = execution->GetOutCallIndex(); + if (!outCallIndexOptional) + { + AddError(nullptr, aznew Internal::ParseError(execution->GetNodeId(), "Execution did not return required out call index")); + return; + } + + const size_t outIndex = *outCallIndexOptional; + + m_dotLua.WriteIndented("%s(self, %zu", Grammar::k_NodeableCallInterpretedOut, outIndex); if (execution->GetInputCount() > 0) { @@ -698,7 +706,7 @@ namespace ScriptCanvas WriteFunctionCallInput(execution); } - m_dotLua.WriteLine(")"); + m_dotLua.WriteLine(") -- %s", execution->GetName().data()); } void GraphToLua::TranslateFunction(Grammar::ExecutionTreeConstPtr execution, IsNamed lex) @@ -861,14 +869,23 @@ namespace ScriptCanvas const bool hasResults = eventThread->HasReturnValues(); + AZStd::optional eventIndex = ebusHandling->m_node->GetEventIndex(eventName); + if (!eventIndex) + { + AddError(nullptr, aznew Internal::ParseError(ebusHandling->m_node->GetEntityId(), AZStd::string::format("EBus handler did not return a valid index for event %s", eventName.c_str()))); + return; + } + m_dotLua.WriteNewLine(); - m_dotLua.WriteLineIndented("%s(%s%s, '%s'," + m_dotLua.WriteLineIndented("%s(%s%s, %zu, -- %s" , hasResults ? Grammar::k_EBusHandlerHandleEventResultName : Grammar::k_EBusHandlerHandleEventName , leftValue.data() , ebusHandling->m_handlerName.data() + , *eventIndex , eventThread->GetName().data()); m_dotLua.Indent(); + TranslateFunction(eventThread, IsNamed::No); m_dotLua.WriteLine(")"); @@ -983,14 +1000,7 @@ namespace ScriptCanvas const auto& outKeys = m_model.GetInterface().GetOutKeys(); if (!outKeys.empty()) { - m_dotLua.WriteIndented("%s(self", Grammar::k_InitializeNodeableOutKeys); - - for (auto& key : outKeys) - { - m_dotLua.Write(", %u", AZ::u32(key)); - } - - m_dotLua.WriteLine(")"); + m_dotLua.WriteLineIndented("%s(self, %zu)", Grammar::k_InitializeNodeableOutKeys, outKeys.size()); } } else @@ -1009,15 +1019,26 @@ namespace ScriptCanvas void GraphToLua::TranslateNodeableOut(Grammar::ExecutionTreeConstPtr execution) { + auto outCallIndexOptional = execution->GetOutCallIndex(); + if (!outCallIndexOptional) + { + AddError(nullptr, aznew Internal::ParseError(execution->GetNodeId(), "Execution did not return required out call index")); + return; + } + + const size_t outIndex = *outCallIndexOptional; + + // #functions2 remove-execution-out-hash const auto setExecutionOutName = Grammar::IsUserFunctionDefinition(execution) ? Grammar::k_NodeableSetExecutionOutUserSubgraphName : execution->HasReturnValues() ? Grammar::k_NodeableSetExecutionOutResultName : Grammar::k_NodeableSetExecutionOutName; - m_dotLua.WriteLineIndented("%s(self.%s, '%s'," + m_dotLua.WriteLineIndented("%s(self.%s, %zu, -- %s" , setExecutionOutName - , execution->GetNodeable()->m_name.data() + , execution->GetNodeable()->m_name.data() + , outIndex , execution->GetName().data()); m_dotLua.Indent(); @@ -1050,7 +1071,6 @@ namespace ScriptCanvas return; } - m_dotLua.WriteIndented("function %s.%s(self, ", m_tableName.c_str(), Grammar::k_InitializeStaticsName); WriteStaticInitializerInput(IsLeadingCommaRequired::No); m_dotLua.WriteLine(")"); @@ -1078,7 +1098,7 @@ namespace ScriptCanvas continue; } - if (variable->m_datum.GetType().GetAZType() == azrtti_typeid()) + if (m_model.IsUserNodeable(variable)) { auto nodeableName = variable->m_name; if (nodeableName.starts_with(Grammar::k_memberNamePrefix)) @@ -1104,7 +1124,7 @@ namespace ScriptCanvas // indexInfo->second.requiresCtorParamsForDependencies // self.nonLeafDependency = NonLeafDependency.new(executionState, UnpackDependencyArgs(executionState, dependentAssets, 7)) // -- has more dependencies, index, known from compile time, pushes the correct asset further down construction - m_dotLua.WriteLineIndented("%s%s = %s.new(%s, %s(%s, %s, %s))" + m_dotLua.WriteLineIndented("%s%s = %s.new(%s, %s(%s, %s, %zu))" , leftValue.data() , variable->m_name.data() , nodeableName.data() @@ -1112,7 +1132,7 @@ namespace ScriptCanvas , Grammar::k_UnpackDependencyConstructionArgsFunctionName , Grammar::k_executionStateVariableName , Grammar::k_DependentAssetsArgName - , AZStd::to_string(indexInfo->first).data()); + , indexInfo->first); } else // vs. @@ -1120,7 +1140,7 @@ namespace ScriptCanvas // !indexInfo->second.hasMoreDependencies // self.leafDependency = LeafDependency.new(executionState, UnpackDependencyArgsLeaf(executionState, dependentAssets, 10)) // -- has NO more dependencies, index, known from compile time - m_dotLua.WriteLineIndented("%s%s = %s.new(%s, %s(%s, %s, %s))" + m_dotLua.WriteLineIndented("%s%s = %s.new(%s, %s(%s, %s, %zu))" , leftValue.data() , variable->m_name.data() , nodeableName.data() @@ -1128,7 +1148,7 @@ namespace ScriptCanvas , Grammar::k_UnpackDependencyConstructionArgsLeafFunctionName , Grammar::k_executionStateVariableName , Grammar::k_DependentAssetsArgName - , AZStd::to_string(indexInfo->first).data()); + , indexInfo->first); } } else @@ -1158,6 +1178,7 @@ namespace ScriptCanvas case Grammar::VariableConstructionRequirement::InputNodeable: m_dotLua.WriteLineIndented("%s:InitializeExecutionState(%s)", variable->m_name.data(), Grammar::k_executionStateVariableName); + m_dotLua.WriteLineIndented("%s:%s()", variable->m_name.c_str(), Grammar::k_InitializeExecutionOutByRequiredCountName); m_dotLua.WriteLineIndented("%s%s = %s", leftValue.data(), variable->m_name.data(), variable->m_name.data()); break; @@ -1227,9 +1248,7 @@ namespace ScriptCanvas void GraphToLua::WriteConstructionDependencyArgs() { - auto& dependencyArgs = m_model.GetOrderedDependencies().orderedAssetIds; - - if (!dependencyArgs.empty()) + if (m_model.GetInterface().RequiresConstructionParametersForDependencies()) { m_dotLua.Write(", %s", Grammar::k_DependentAssetsArgName); } @@ -1740,7 +1759,7 @@ namespace ScriptCanvas size_t GraphToLua::WriteFunctionCallInputThisPointer(Grammar::ExecutionTreeConstPtr execution) { - if (IsUserFunctionCall(execution) && execution->GetRoot()->IsPure()) + if (IsUserFunctionCallPure(execution)) { m_dotLua.Write("%s", Grammar::k_executionStateVariableName); diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp index 315d786712..bbcbde5c6c 100644 --- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp @@ -37,10 +37,10 @@ namespace ScriptCanvasSystemComponentCpp { #if !defined(_RELEASE) && !defined(PERFORMANCE_BUILD) - const int k_infiniteLoopDetectionMaxIterations = 3000; + const int k_infiniteLoopDetectionMaxIterations = 1000000; const int k_maxHandlerStackDepth = 25; #else - const int k_infiniteLoopDetectionMaxIterations = 10000; + const int k_infiniteLoopDetectionMaxIterations = 10000000; const int k_maxHandlerStackDepth = 100; #endif diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionCycle10.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionCycle10.scriptcanvas new file mode 100644 index 0000000000..81af42910c --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionCycle10.scriptcanvas @@ -0,0 +1,3216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionOutPerformance.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionOutPerformance.scriptcanvas new file mode 100644 index 0000000000..9ec8c01d35 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ExecutionOutPerformance.scriptcanvas @@ -0,0 +1,5753 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunction.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunction.scriptcanvas new file mode 100644 index 0000000000..36be46edc9 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunction.scriptcanvas @@ -0,0 +1,628 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunctionNotPure.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunctionNotPure.scriptcanvas new file mode 100644 index 0000000000..2e6439c95b --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_HelloWorldFunctionNotPure.scriptcanvas @@ -0,0 +1,733 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfNotPureUserFunction.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfNotPureUserFunction.scriptcanvas new file mode 100644 index 0000000000..eb208d7fd2 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfNotPureUserFunction.scriptcanvas @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfPureUserFunction.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfPureUserFunction.scriptcanvas new file mode 100644 index 0000000000..1140c64bbd --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_LatentCallOfPureUserFunction.scriptcanvas @@ -0,0 +1,750 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h index cb3c9cdccb..ab00593dbc 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h @@ -108,9 +108,15 @@ namespace ScriptCanvasTests auto m_serializeContext = s_application->GetSerializeContext(); auto m_behaviorContext = s_application->GetBehaviorContext(); - - ScriptCanvasTesting::Reflect(m_serializeContext); - ScriptCanvasTesting::Reflect(m_behaviorContext); + ScriptCanvasTesting::GlobalBusTraits::Reflect(m_serializeContext); + ScriptCanvasTesting::GlobalBusTraits::Reflect(m_behaviorContext); + ScriptCanvasTesting::LocalBusTraits::Reflect(m_serializeContext); + ScriptCanvasTesting::LocalBusTraits::Reflect(m_behaviorContext); + ScriptCanvasTesting::PerformanceStressBusTraits::Reflect(m_serializeContext); + ScriptCanvasTesting::PerformanceStressBusTraits::Reflect(m_behaviorContext); + ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_serializeContext); + ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(m_behaviorContext); + ScriptCanvasTesting::TestTupleMethods::Reflect(m_behaviorContext); ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_serializeContext); ::Nodes::InputMethodSharedDataSlotExampleNode::Reflect(m_behaviorContext); diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp index 34df10fdea..dc43bb862d 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.cpp @@ -130,6 +130,87 @@ namespace ScriptCanvasTesting } } + class PerformanceStressEBusHandler + : public PerformanceStressEBus::Handler + , public AZ::BehaviorEBusHandler + { + public: + AZ_EBUS_BEHAVIOR_BINDER( + PerformanceStressEBusHandler, "{EAE36675-F06B-4755-B3A5-CEC9495DC92E}", AZ::SystemAllocator + , ForceStringCompare0 + , ForceStringCompare1 + , ForceStringCompare2 + , ForceStringCompare3 + , ForceStringCompare4 + , ForceStringCompare5 + , ForceStringCompare6 + , ForceStringCompare7 + , ForceStringCompare8 + , ForceStringCompare9 + ); + + void ForceStringCompare0() override + { + Call(FN_ForceStringCompare0); + } + void ForceStringCompare1() override + { + Call(FN_ForceStringCompare1); + } + void ForceStringCompare2() override + { + Call(FN_ForceStringCompare2); + } + void ForceStringCompare3() override + { + Call(FN_ForceStringCompare3); + } + void ForceStringCompare4() override + { + Call(FN_ForceStringCompare4); + } + void ForceStringCompare5() override + { + Call(FN_ForceStringCompare5); + } + void ForceStringCompare6() override + { + Call(FN_ForceStringCompare6); + } + void ForceStringCompare7() override + { + Call(FN_ForceStringCompare7); + } + void ForceStringCompare8() override + { + Call(FN_ForceStringCompare8); + } + void ForceStringCompare9() override + { + Call(FN_ForceStringCompare9); + } + }; + + void PerformanceStressBusTraits::Reflect(AZ::ReflectContext* context) + { + if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) + { + behaviorContext->EBus("PerformanceStressEBus") + ->Handler() + ->Event("ForceStringCompare0", &PerformanceStressEBus::Events::ForceStringCompare0) + ->Event("ForceStringCompare1", &PerformanceStressEBus::Events::ForceStringCompare1) + ->Event("ForceStringCompare2", &PerformanceStressEBus::Events::ForceStringCompare2) + ->Event("ForceStringCompare3", &PerformanceStressEBus::Events::ForceStringCompare3) + ->Event("ForceStringCompare4", &PerformanceStressEBus::Events::ForceStringCompare4) + ->Event("ForceStringCompare5", &PerformanceStressEBus::Events::ForceStringCompare5) + ->Event("ForceStringCompare6", &PerformanceStressEBus::Events::ForceStringCompare6) + ->Event("ForceStringCompare7", &PerformanceStressEBus::Events::ForceStringCompare7) + ->Event("ForceStringCompare8", &PerformanceStressEBus::Events::ForceStringCompare8) + ->Event("ForceStringCompare9", &PerformanceStressEBus::Events::ForceStringCompare9) + ; + } + } + class LocalEBusHandler : public LocalEBus::Handler , public AZ::BehaviorEBusHandler diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h index c31627f9fb..5aa8c3c3ec 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestBus.h @@ -46,6 +46,27 @@ namespace ScriptCanvasTesting }; using GlobalEBus = AZ::EBus; + class PerformanceStressBusTraits : public AZ::EBusTraits + { + public: + AZ_TYPE_INFO(PerformanceStressBusTraits, "{68AF0B81-70F4-4822-8127-AAC442D924C7}"); + + static void Reflect(AZ::ReflectContext* context); + + virtual void ForceStringCompare0() = 0; + virtual void ForceStringCompare1() = 0; + virtual void ForceStringCompare2() = 0; + virtual void ForceStringCompare3() = 0; + virtual void ForceStringCompare4() = 0; + virtual void ForceStringCompare5() = 0; + virtual void ForceStringCompare6() = 0; + virtual void ForceStringCompare7() = 0; + virtual void ForceStringCompare8() = 0; + virtual void ForceStringCompare9() = 0; + }; + using PerformanceStressEBus = AZ::EBus; + + class LocalBusTraits : public AZ::EBusTraits { public: diff --git a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp index e6bd4f53cf..281ca211a3 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/ScriptCanvasTestingSystemComponent.cpp @@ -43,7 +43,11 @@ namespace ScriptCanvasTesting NodeableTestingLibrary::Reflect(context); ScriptCanvasTestingNodes::BehaviorContextObjectTest::Reflect(context); - ScriptCanvasTesting::Reflect(context); + ScriptCanvasTesting::GlobalBusTraits::Reflect(context); + ScriptCanvasTesting::LocalBusTraits::Reflect(context); + ScriptCanvasTesting::PerformanceStressBusTraits::Reflect(context); + ScriptCanvasTesting::NativeHandlingOnlyBusTraits::Reflect(context); + ScriptCanvasTesting::TestTupleMethods::Reflect(context); } void ScriptCanvasTestingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 9e6f7aa051..53f124476f 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -283,6 +283,16 @@ TEST_F(ScriptCanvasTestFixture, NodeableDurationFunction) ExpectParse("LY_SC_UnitTest_NodeableDurationFunction"); } +TEST_F(ScriptCanvasTestFixture, LatentCallOfPureUserFunction) +{ + RunUnitTestGraph("LY_SC_UnitTest_LatentCallOfPureUserFunction", ExecutionMode::Interpreted, DurationSpec::Ticks(3)); +} + +TEST_F(ScriptCanvasTestFixture, LatentCallOfNotPureUserFunction) +{ + RunUnitTestGraph("LY_SC_UnitTest_LatentCallOfNotPureUserFunction", ExecutionMode::Interpreted, DurationSpec::Ticks(3)); +} + TEST_F(ScriptCanvasTestFixture, NodeableDurationSubgraph) { RunUnitTestGraph("LY_SC_UnitTest_NodeableDurationSubgraph", ExecutionMode::Interpreted, DurationSpec::Ticks(3)); @@ -887,6 +897,11 @@ TEST_F(ScriptCanvasTestFixture, InterpretedNodeableInputMethodSharedDataSlot) RunUnitTestGraph("LY_SC_UnitTest_NodeableInputMethodSharedDataSlot", ExecutionMode::Interpreted); } +TEST_F(ScriptCanvasTestFixture, InterpretedExecutionOutPerformance) +{ + RunUnitTestGraph("LY_SC_UnitTest_ExecutionOutPerformance", ExecutionMode::Interpreted); +} + #if defined(FUNCTION_LEGACY_SUPPORT_ENABLED) TEST_F(ScriptCanvasTestFixture, InterpretedSubgraph_UserNodeable)