diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 9b2ccbe754..39f6c02bde 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -146,7 +146,7 @@ namespace AZ { AZStd::mutex g_dbgLoadingMutex; HANDLE g_currentProcess = 0; /// We deal with only one process for now. CRITICAL_SECTION g_csDbgHelpDll; /// All dbg help functions are single threaded, so we need to control the access. - AZStd::fixed_vector g_moduleInfo; + AZStd::fixed_vector g_moduleInfo; // reserve 4k of scratch space so that we can get some callstack information without any allocations and as little stack frame usage as possible. const size_t g_scratchSpaceSize = 2048; diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp index e698fcc298..2bc3a91a96 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp @@ -58,16 +58,6 @@ namespace ScriptCanvasEditor required.push_back(AZ_CRC("ScriptCanvasService", 0x41fd58f3)); } - ScriptCanvas::Grammar::Context* EditorAssetSystemComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* EditorAssetSystemComponent::GetTranslationContext() - { - return &m_translationContext; - } - void EditorAssetSystemComponent::Init() { } @@ -79,16 +69,10 @@ namespace ScriptCanvasEditor AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); EditorAssetConversionBus::Handler::BusConnect(); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void EditorAssetSystemComponent::Deactivate() { - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - EditorAssetConversionBus::Handler::BusDisconnect(); AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); m_editorAssetRegistry.Unregister(); diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h index 4a55a35908..84b10ff17c 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.h @@ -12,11 +12,6 @@ #include "EditorAssetConversionBus.h" #include #include - -#include -#include -#include -#include #include namespace ScriptCanvasEditor @@ -26,8 +21,6 @@ namespace ScriptCanvasEditor class EditorAssetSystemComponent : public AZ::Component , public EditorAssetConversionBus::Handler - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler , private AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler { public: @@ -60,20 +53,10 @@ namespace ScriptCanvasEditor AZ::Outcome CreateLuaAsset(const AZ::Data::Asset& editAsset, AZStd::string_view graphPathForRawLuaFile) override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler... - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler... - ScriptCanvas::Translation::Context* GetTranslationContext() override; - - ScriptCanvas::AssetRegistry& GetAssetRegistry(); private: - ScriptCanvas::AssetRegistry m_editorAssetRegistry; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; - + ScriptCanvas::AssetRegistry m_editorAssetRegistry; EditorAssetSystemComponent(const EditorAssetSystemComponent&) = delete; }; } diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp index 2f30106707..b37d5c1da4 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp @@ -104,9 +104,6 @@ namespace ScriptCanvasBuilder m_sharedHandlers = HandleAssetTypes(); AssetHandlers workerHandlers(m_sharedHandlers); m_scriptCanvasBuilder.Activate(workerHandlers); - - ScriptCanvas::Translation::RequestBus::Handler::BusConnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusConnect(); } void PluginComponent::Deactivate() @@ -116,18 +113,6 @@ namespace ScriptCanvasBuilder AzToolsFramework::ToolsAssetSystemBus::Broadcast(&AzToolsFramework::ToolsAssetSystemRequests::UnregisterSourceAssetType, azrtti_typeid()); m_scriptCanvasBuilder.BusDisconnect(); m_sharedHandlers.DeleteOwnedHandlers(); - ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - } - - ScriptCanvas::Grammar::Context* PluginComponent::GetGrammarContext() - { - return &m_grammarContext; - } - - ScriptCanvas::Translation::Context* PluginComponent::GetTranslationContext() - { - return &m_translationContext; } void PluginComponent::Reflect(AZ::ReflectContext* context) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h index 5d57863ec3..ff904d195a 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.h @@ -12,18 +12,11 @@ #include #include "ScriptCanvasBuilderWorker.h" -#include -#include -#include -#include - namespace ScriptCanvasBuilder { //! ScriptCanvasBuilder is responsible for turning editor ScriptCanvas Assets into runtime script canvas assets class PluginComponent : public AZ::Component - , public ScriptCanvas::Grammar::RequestBus::Handler - , public ScriptCanvas::Translation::RequestBus::Handler { public: AZ_COMPONENT(PluginComponent, "{F8286B21-E751-4745-8BC4-512F190215FF}") @@ -42,19 +35,9 @@ namespace ScriptCanvasBuilder void Deactivate() override; ////////////////////////////////////////////////////////////////////////// - // ScriptCanvas::Grammar::RequestBus::Handler - ScriptCanvas::Grammar::Context* GetGrammarContext() override; - - // ScriptCanvas::Translation::RequestBus::Handler - ScriptCanvas::Translation::Context* GetTranslationContext() override; - private: PluginComponent(const PluginComponent&) = delete; - SharedHandlers m_sharedHandlers; - Worker m_scriptCanvasBuilder; - ScriptCanvas::Translation::Context m_translationContext; - ScriptCanvas::Grammar::Context m_grammarContext; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp index 8250eb1763..3f9c5cc8a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.cpp @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include // Version Conversion includes @@ -2335,6 +2333,11 @@ namespace ScriptCanvas } } + bool Node::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, [[maybe_unused]] const Slot& inputSlot) const + { + return true; + } + void Node::CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const { for (const Slot& slot : m_slots) @@ -2949,45 +2952,6 @@ namespace ScriptCanvas } } - void Node::SetInput(const Datum& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Datum&& newInput, const SlotId& slotId) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - - ModifiableDatumView datumView; - FindModifiableDatumView(slotId, datumView); - - if (datumView.IsValid()) - { - datumView.AssignToDatum(newInput); - } - } - - void Node::SetInput(Node& node, const SlotId& id, const Datum& input) - { - AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::ScriptCanvas); - node.SetInput(input, id); - } - - void Node::SetInput(Node& node, const SlotId& id, Datum&& input) - { - AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::ScriptCanvas, "ScriptCanvas::Node::SetInput"); - - node.SetInput(AZStd::move(input), id); - } - AZStd::string Node::GetDebugName() const { if (GetEntityId().IsValid()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h index 55379e29b9..614494883a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Node.h @@ -479,7 +479,10 @@ namespace ScriptCanvas Node(const Node&); // Needed just for DLL linkage. Does not perform a copy Node& operator=(const Node&); // Needed just for DLL linkage. Does not perform a copy + virtual bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const; + virtual void CollectVariableReferences(AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; + virtual bool ContainsReferencesToVariables(const AZStd::unordered_set< ScriptCanvas::VariableId >& variableIds) const; Graph* GetGraph() const; @@ -841,9 +844,6 @@ namespace ScriptCanvas void SignalSlotsReordered(); - static void SetInput(Node& node, const SlotId& id, const Datum& input); - static void SetInput(Node& node, const SlotId& id, Datum&& input); - // Will ignore any references and return the Datum that the slot represents. void ModifyUnderlyingSlotDatum(const SlotId& id, ModifiableDatumView& datumView); @@ -995,9 +995,6 @@ protected: void SetOwningScriptCanvasId(ScriptCanvasId scriptCanvasId); void SetGraphEntityId(AZ::EntityId graphEntityId); - virtual void SetInput(const Datum& input, const SlotId& id); - virtual void SetInput(Datum&& input, const SlotId& id); - bool SlotExists(AZStd::string_view name, const SlotDescriptor& slotDescriptor) const; bool IsTargetInDataFlowPath(const ID& targetNodeId, AZStd::unordered_set& path) const; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index f3d6070ac6..01b754506c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -9,8 +9,6 @@ #include #include -#include -#include namespace NodeableOutCpp { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp index 5ec40d8e5f..db0cf8e589 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNode.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp index c9e2e3acc6..882804de36 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/NodeableNodeOverloaded.cpp @@ -12,8 +12,6 @@ #include #include #include -#include -#include #include #include diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 348c89f45f..4ccb462a5d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -32,7 +32,6 @@ #include "AbstractCodeModel.h" #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" @@ -670,6 +669,28 @@ namespace ScriptCanvas return AddVariable(Datum(type), rawName); } + void AbstractCodeModel::CheckForKnownNullDereference(ExecutionTreeConstPtr execution, const ExecutionInput& input, const Slot& inputSlot) + { + if (Data::IsValueType(inputSlot.GetDataType()) + || !execution->GetId().m_node + || !execution->GetId().m_slot + || (input.m_value && !input.m_value->m_datum.Empty())) + { + return; + } + + if (!input.m_value) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, "Internal Error: CheckForKnownNullDereference called with input with no m_value"); + return; + } + + if (!execution->GetId().m_node->CanAcceptNullInput(*execution->GetId().m_slot, inputSlot)) + { + AddError(execution->GetId().m_node->GetEntityId(), nullptr, ParseErrors::NullInputKnown); + } + } + void AbstractCodeModel::CheckConversion(ConversionByIndex& conversion, VariableConstPtr source, size_t index, const Data::Type& targetType) { const Data::Type& sourceType = source->m_datum.GetType(); @@ -698,7 +719,7 @@ namespace ScriptCanvas } AZStd::string AbstractCodeModel::CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut) @@ -2422,17 +2443,17 @@ namespace ScriptCanvas ExecutionTreePtr start = OpenScope(nullptr, startNode, nullptr); start->SetSymbol(Symbol::FunctionDefinition); + m_start = start; // cache the function definition if (!m_subgraphStartCalls.empty()) { - m_start = start; - + // call OnGraphStart on all the member nodeables first for (auto node : m_subgraphStartCalls) { ExecutionTreePtr childStartCall = CreateChild(start, node, nullptr); childStartCall->SetSymbol(Symbol::FunctionCall); childStartCall->SetName(k_OnGraphStartFunctionName); - childStartCall->MarkStart(); + childStartCall->MarkStartCall(); auto lexicalScopeOutcome = node->GetFunctionCallLexicalScope(nullptr); @@ -2478,11 +2499,13 @@ namespace ScriptCanvas } } + // ExecutionTreePtr start is now either the last child start() call, or the beginning of the function block, + // either way, parsing can continue from the ExecutionTreePtr start. + if (!outSlots.empty()) { start->AddChild({ outSlots[0], {}, nullptr }); - start->MarkStart(); - + ParseExecutionMultipleOutSyntaxSugar(start, outNodes, outSlots); PostParseProcess(start); PostParseErrorDetect(start); @@ -2490,24 +2513,10 @@ namespace ScriptCanvas if (!IsErrorFree()) { start->Clear(); - - if (m_start) - { - m_start->Clear(); - } - + m_start->Clear(); AddError(AZ::EntityId{}, nullptr, ScriptCanvas::ParseErrors::StartNodeFailedToParse); return; } - - if (!m_start) - { - m_start = start; - } - } - else - { - // add warning or notification on useless start node? } if (m_start) @@ -4297,10 +4306,7 @@ namespace ScriptCanvas void AbstractCodeModel::ParseInputDatum(ExecutionTreePtr execution, const Slot& input) { - // \todo look for crossed lines in inferred functions, because sometimes, rather than the input - // being named of the result of the output that emitted it, it will be the name of the inferred function - // parameter ---> make a map of node output to function input names - AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input should have been handled already"); + AZ_Assert(execution->GetSymbol() != Symbol::FunctionDefinition, "Function definition input is not handled in AbstractCodeModel::ParseInputDatum"); auto nodes = execution->GetId().m_node->GetConnectedNodes(input); if (nodes.empty()) @@ -4310,17 +4316,6 @@ namespace ScriptCanvas execution->AddInput({ &input, variable, DebugDataSource::FromVariable(input.GetId(), input.GetDataType(), variable->m_sourceVariableId) }); CheckConversion(execution->ModConversions(), variable, execution->GetInputCount() - 1, input.GetDataType()); } - // This concept may never actually be possible -// else if (RequiresCreationFunction(input.GetDataType().GetType())) -// { -// AddError(execution, aznew NotYetImplemented( -// "1: finish input created by name when connected to other nodes" -// "2: add the name to the scope" -// "3: and check inputs be re-used, common constructors like zero/1, etc" -// "4: read the variable name if it is present instead of creating it" -// "5: check for entity references to self and other member slice variables" -// "6: mark the variable with RequiredCreationFunction()")); -// } else { auto variableDatum = input.FindDatum(); @@ -4357,26 +4352,30 @@ namespace ScriptCanvas } else { - // we don't support this, yet, but visually we could - // we could support both things, technically...auto-generated inputs, and defaults on the non-connected - // execution thread, or whatever makes possible sense - // \todo send enough information to reveal the data path in the editor - + // This isn't supported visually, yet, but technically, it could be. + // One could connect both latent execution and immediate execution to the same code execution path, + // but only one uses connected output, and the other uses defaults. + // It would require us to change the visualization of the shared path, based on which parent was clicked on in the editor. const auto& targetNode = *execution->GetId().m_node; const auto& targetSlot = input; for (auto sourceNodeAndSlot : nodes) { AddError(nullptr, aznew ScopedDataConnectionEvent - (execution->GetNodeId() + ( execution->GetNodeId() , targetNode , targetSlot , *sourceNodeAndSlot.first , *sourceNodeAndSlot.second)); } + + return; } } + + // Check for known null reads + CheckForKnownNullDereference(execution, execution->GetInput(execution->GetInputCount() - 1), input); } bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution) @@ -4428,6 +4427,7 @@ namespace ScriptCanvas if (auto eventHandling = GetEBusEventHandling(node)) { auto variable = AZStd::make_shared(); + variable->m_isMember = true; variable->m_datum = Datum(eventHandling->m_handlerName); execution->MarkInputHasThisPointer(); execution->AddInput({ nullptr, variable, DebugDataSource::FromInternal() }); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index 06854fdbfd..45e289739d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -207,8 +207,10 @@ namespace ScriptCanvas bool CheckCreateRoot(const Node& node); + void CheckForKnownNullDereference(ExecutionTreeConstPtr parent, const ExecutionInput& input, const Slot& inputSlot); + AZStd::string CheckUniqueInterfaceNames - (AZStd::string_view candidate + ( AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp index 1ac9303082..6ac80de542 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp @@ -27,7 +27,6 @@ #include #include "ExecutionTraversalListeners.h" -#include "GrammarContextBus.h" #include "ParsingUtilities.h" #include "Primitives.h" diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp deleted file mode 100644 index b8eb5f5ad5..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.cpp +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#include "GrammarContext.h" - -namespace ScriptCanvas -{ - namespace Grammar - { - const SubgraphInterfaceSystem& Context::GetExecutionMapSystem() const - { - return m_executionMapSystem; - } - - SubgraphInterfaceSystem& Context::ModExecutionMapSystem() - { - return m_executionMapSystem; - } - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h deleted file mode 100644 index 7a9d2eaec9..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContext.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include -#include - -#include - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context - { - public: - AZ_CLASS_ALLOCATOR(Context, AZ::SystemAllocator, 0); - - Context() = default; - ~Context() = default; - - const SubgraphInterfaceSystem& GetExecutionMapSystem() const; - SubgraphInterfaceSystem& ModExecutionMapSystem(); - - private: - SubgraphInterfaceSystem m_executionMapSystem; - - // put grammatical state globals in here, things that can be useful across several parses of graphs - }; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h deleted file mode 100644 index 1630d0b99e..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/GrammarContextBus.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -namespace ScriptCanvas -{ - namespace Grammar - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetGrammarContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - // add stuff here to speed up parsing across separate graphs - }; - - using EventBus = AZ::EBus; - } - -} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index 0984440bf4..011dfeda97 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -354,9 +354,9 @@ namespace ScriptCanvas return GetRoot()->m_isPure; } - bool ExecutionTree::IsStart() const + bool ExecutionTree::IsStartCall() const { - return m_isStart; + return m_isStartCall; } void ExecutionTree::MarkDebugEmptyStatement() @@ -403,9 +403,9 @@ namespace ScriptCanvas root->m_isLatent = true; } - void ExecutionTree::MarkStart() + void ExecutionTree::MarkStartCall() { - m_isStart = true; + m_isStartCall = true; } ExecutionChild& ExecutionTree::ModChild(size_t index) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h index c86f445a68..80d602ad17 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.h @@ -199,7 +199,7 @@ namespace ScriptCanvas bool IsPure() const; - bool IsStart() const; + bool IsStartCall() const; void MarkDebugEmptyStatement(); @@ -215,7 +215,7 @@ namespace ScriptCanvas void MarkRootLatent(); - void MarkStart(); + void MarkStartCall(); ExecutionChild& ModChild(size_t index); @@ -286,7 +286,7 @@ namespace ScriptCanvas bool m_isPure = false; - bool m_isStart = false; + bool m_isStartCall = false; bool m_hasExplicitUserOutCalls = false; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 32b5e5741f..4eafa82331 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -25,6 +25,7 @@ namespace MethodCPP Unnamed2, PluralizeResults, AddedPrettyNameFieldToSerialization, + StoreInputSlotIdsToSupportNullCheck, // add your version above Current, }; @@ -110,6 +111,37 @@ namespace ScriptCanvas { namespace Core { + bool Method::CanAcceptNullInput([[maybe_unused]] const Slot& executionSlot, const Slot& inputSlot) const + { + if (m_method) + { + auto candidateID = inputSlot.GetId(); + auto slotIter = AZStd::find(m_inputSlots.begin(), m_inputSlots.end(), candidateID); + + if (slotIter != m_inputSlots.end()) + { + const size_t index = slotIter - m_inputSlots.begin(); + if (index < m_method->GetNumArguments()) + { + const auto* argument = m_method->GetArgument(index); + if (argument->m_traits & (AZ::BehaviorParameter::TR_REFERENCE | AZ::BehaviorParameter::TR_THIS_PTR)) + { + // references and this pointers cannot accept null input + return false; + } + + if (!(argument->m_traits & AZ::BehaviorParameter::TR_POINTER)) + { + // values cannot accept null input + return false; + } + } + } + } + + return true; + } + const AZ::BehaviorClass* Method::GetClass() const { return m_class; @@ -232,6 +264,11 @@ namespace ScriptCanvas if (addedSlot.IsValid()) { MethodHelper::SetSlotToDefaultValue(*this, addedSlot, config, argIndex); + m_inputSlots.push_back(addedSlot); + } + else + { + AZ_Warning("ScriptCanvas", false, "Failed to add method input slot to Method node: %s-%s", config.m_prettyClassName.c_str(), config.m_method.m_name.c_str()); } } } @@ -520,8 +557,8 @@ namespace ScriptCanvas if (m_method && m_method->HasResult()) { if (branchOnResultMethod.GetNumArguments() == 1 - && branchOnResultMethod.HasResult() - && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) + && branchOnResultMethod.HasResult() + && Data::FromAZType(branchOnResultMethod.GetResult()->m_typeId) == Data::Type::Boolean()) { AZ::Uuid methodResultType = m_method->GetResult()->m_typeId; AZ::Uuid branchOnResultMethodArgType = branchOnResultMethod.GetArgument(0)->m_typeId; @@ -797,6 +834,7 @@ namespace ScriptCanvas ->Field("className", &Method::m_className) ->Field("namespaces", &Method::m_namespaces) ->Field("resultSlotIDs", &Method::m_resultSlotIDs) + ->Field("inputSlots", &Method::m_inputSlots) ->Field("prettyClassName", &Method::m_classNamePretty) ; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index db34da040c..3dec8e3e72 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -45,6 +45,8 @@ namespace ScriptCanvas size_t GenerateFingerprint() const override; + bool CanAcceptNullInput(const Slot& executionSlot, const Slot& inputSlot) const override; + bool GetBranchOnResultCheckName(AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; virtual bool GetCheckedOperationInfo(AZ::CheckedOperationInfo& checkedInfo, AZStd::string& exposedName, Grammar::LexicalScope& lexicalScope) const; @@ -149,8 +151,6 @@ namespace ScriptCanvas bool IsExpectingResult() const; - AZ_INLINE AZStd::vector& ModResultSlotIds() { return m_resultSlotIDs; } - virtual void OnInitializeOutputPost(const MethodOutputConfig&) {} virtual void OnInitializeOutputPre(MethodOutputConfig&) {} @@ -176,6 +176,7 @@ namespace ScriptCanvas NamespacePath m_namespaces; const AZ::BehaviorMethod* m_method = nullptr; const AZ::BehaviorClass* m_class = nullptr; + AZStd::vector m_inputSlots; AZStd::vector m_resultSlotIDs; AZStd::recursive_mutex m_mutex; // post-serialization bool m_warnOnMissingFunction = true; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h index 339c0fc3a1..928d1d7202 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Results/ErrorText.h @@ -74,6 +74,7 @@ namespace ScriptCanvas constexpr const char* NotEnoughBranchesForReturn = "Not enough branches for defined out return values."; constexpr const char* NotEnoughInputForArithmeticOperator = "Not enough input for arithmetic operator"; constexpr const char* NullEntityInGraph = "Null entity pointer in graph"; + constexpr const char* NullInputKnown = "The input is known to be null, and the node does not accept it"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarChildExecutionRemovedAndNotReplaced = "ParseExecutionMultipleOutSyntaxSugar: child execution node was removed, and not replaced."; constexpr const char* ParseExecutionMultipleOutSyntaxSugarMismatchOutSize = "ParseExecutionMultipleOutSyntaxSugar: mismatch in connect nodes vs source slots size"; constexpr const char* ParseExecutionMultipleOutSyntaxSugarNonNullChildExecutionFound = "ParseExecutionMultipleOutSyntaxSugar: non null child execution node"; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp index 772fda4f7e..085a0928bc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.cpp @@ -24,8 +24,6 @@ #include #include "GraphToLuaUtility.h" -#include "TranslationContext.h" -#include "TranslationContextBus.h" namespace GraphToLuaCpp { @@ -92,9 +90,7 @@ namespace ScriptCanvas { SystemRequestBus::BroadcastResult(m_systemConfiguration, &SystemRequests::GetSystemComponentConfiguration); MarkTranslationStart(); - RequestBus::BroadcastResult(m_context, &RequestTraits::GetTranslationContext); - AZ_Assert(m_context, "Nothing is possible without the context"); - + m_tableName = GraphToLuaCpp::FileNameToTableName(m_model.GetSource().m_name); m_tableName += m_configuration.m_suffix; @@ -138,12 +134,12 @@ namespace ScriptCanvas const AZStd::string& GraphToLua::FindAbbreviation(AZStd::string_view dependency) const { - return m_context->FindAbbreviation(dependency); + return m_context.FindAbbreviation(dependency); } const AZStd::string& GraphToLua::FindLibrary(AZStd::string_view dependency) const { - return m_context->FindLibrary(dependency); + return m_context.FindLibrary(dependency); } AZStd::string_view GraphToLua::GetOperatorString(Grammar::ExecutionTreeConstPtr execution) @@ -806,7 +802,7 @@ namespace ScriptCanvas m_dotLua.Write("("); - if (execution->IsStart() && execution->IsPure()) + if (execution == m_model.GetStart() && execution->IsPure()) { m_dotLua.Write(Grammar::k_executionStateVariableName); @@ -1589,8 +1585,10 @@ namespace ScriptCanvas break; } - // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables -// if (execution->IsStart() && execution->IsPure()) + // #functions2 pure on graph start nodes with dependencies can only be added to the graph as variables, which is a work-flow we may never want to support + // as it effectively duplicates the Component-Entity-System. Technically, if this functionality is desired, one could just add another script component + // with the additional graph... +// if (execution->IsStartCall() && execution->IsPure()) // { // WriteFunctionCallInputOfChildStart(execution); // } @@ -1944,7 +1942,7 @@ namespace ScriptCanvas { const auto requirement = ParseConstructionRequirement(variable); - if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStart())) + if (requirement == Grammar::VariableConstructionRequirement::None || (requirement != Grammar::VariableConstructionRequirement::Static && !execution->IsStartCall())) { m_dotLua.WriteLineIndented("local %s = %s", variable->m_name.data(), ToValueString(variable->m_datum, m_configuration).data()); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h index ba46b21c65..347cb764e9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToLua.h @@ -16,6 +16,7 @@ #include #include "GraphToX.h" +#include "TranslationContext.h" #include "TranslationResult.h" #include "TranslationUtilities.h" @@ -60,7 +61,7 @@ namespace ScriptCanvas RuntimeInputs m_runtimeInputs; BuildConfiguration m_executionConfig = BuildConfiguration::Release; FunctionBlockConfig m_functionBlockConfig = FunctionBlockConfig::Ignored; - const Context* m_context = nullptr; + Context m_context; AZStd::string m_tableName; Writer m_dotLua; SystemComponentConfiguration m_systemConfiguration; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h index ea49f90bde..40f04f2f47 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContext.h @@ -10,7 +10,6 @@ #include #include #include "Translation.h" -#include "TranslationContextBus.h" namespace ScriptCanvas { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h deleted file mode 100644 index 0edac2afe3..0000000000 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationContextBus.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution. - * - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - */ - -#pragma once - -#include - -#include "Translation.h" - -namespace ScriptCanvas -{ - namespace Translation - { - class Context; - - struct RequestTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - - virtual Context* GetTranslationContext() = 0; - }; - - using RequestBus = AZ::EBus; - - struct EventTraits : public AZ::EBusTraits - { - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - }; - - using EventBus = AZ::EBus; - - } - -} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 40b5786303..17273b7ae0 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -101,7 +101,6 @@ set(FILES Include/ScriptCanvas/Translation/Translation.cpp Include/ScriptCanvas/Translation/TranslationContext.h Include/ScriptCanvas/Translation/TranslationContext.cpp - Include/ScriptCanvas/Translation/TranslationContextBus.h Include/ScriptCanvas/Translation/TranslationResult.h Include/ScriptCanvas/Translation/TranslationResult.cpp Include/ScriptCanvas/Translation/TranslationUtilities.h @@ -196,9 +195,6 @@ set(FILES Include/ScriptCanvas/Grammar/DebugMap.cpp Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.h Include/ScriptCanvas/Grammar/ExecutionTraversalListeners.cpp - Include/ScriptCanvas/Grammar/GrammarContext.h - Include/ScriptCanvas/Grammar/GrammarContext.cpp - Include/ScriptCanvas/Grammar/GrammarContextBus.h Include/ScriptCanvas/Grammar/ParsingMetaData.h Include/ScriptCanvas/Grammar/ParsingMetaData.cpp Include/ScriptCanvas/Grammar/ParsingUtilities.h diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas new file mode 100644 index 0000000000..4453617996 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ParseErrorOnKnownNull.scriptcanvas @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp index 727f73be39..e54c83c5d3 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestNodes.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index 107bb32cd6..db3d2223d6 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include @@ -85,6 +83,16 @@ public: } }; +TEST_F(ScriptCanvasTestFixture, ProveError) +{ + EXPECT_TRUE(false); +} + +TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) +{ + ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); +} + TEST_F(ScriptCanvasTestFixture, UseBehaviorContextClassConstant) { RunUnitTestGraph("LY_SC_UnitTest_UseBehaviorContextClassConstant"); diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp index 0733101743..8c4983da0f 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_VM.cpp @@ -14,8 +14,6 @@ #include #include #include -#include -#include #include #include #include