From cb7a26ce5e11938709d27aa161909e064c98fc98 Mon Sep 17 00:00:00 2001 From: chcurran Date: Thu, 22 Apr 2021 16:13:24 -0700 Subject: [PATCH] Editor for stability and overloaded nodes. LYN-2904, LYN-3059, LYN-3234, LYN-2888 --- .../Code/Editor/Nodes/NodeDisplayUtils.cpp | 3 +- .../Widgets/NodePalette/NodePaletteModel.cpp | 2 +- .../Grammar/AbstractCodeModel.cpp | 32 ++++++---- .../ScriptCanvas/Grammar/Primitives.cpp | 15 ++++- .../Grammar/PrimitivesExecution.cpp | 5 +- .../ScriptCanvas/Libraries/Core/Method.cpp | 61 +++++++++++++++---- .../ScriptCanvas/Libraries/Core/Method.h | 4 +- 7 files changed, 90 insertions(+), 32 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp index c6ecac00f1..a903c9f885 100644 --- a/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Nodes/NodeDisplayUtils.cpp @@ -332,7 +332,8 @@ namespace ScriptCanvasEditor::Nodes contextGroup = TranslationContextGroup::ClassMethod; break; default: - AZ_Assert(false, "Invalid node type"); + AZ_Error("ScriptCanvas", false, "Invalid method node type, node creation failed. This node nodes to be deleted."); + break; } graphCanvasEntity->Init(); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp index 2edc950e6f..6028b284fa 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/NodePalette/NodePaletteModel.cpp @@ -136,7 +136,7 @@ namespace return; } - if (behaviorClass) + if (behaviorClass && !isOverloaded) { auto excludeMethodAttributeData = azdynamic_cast*>(AZ::FindAttribute(AZ::Script::Attributes::ExcludeFrom, method.m_attributes)); if (ShouldExcludeFromNodeList(excludeMethodAttributeData, behaviorClass->m_azRtti ? behaviorClass->m_azRtti->GetTypeId() : behaviorClass->m_typeId)) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 958e37f82c..3bc105d1dd 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -146,7 +146,10 @@ namespace ScriptCanvas for (auto iter : m_functions) { - AZStd::const_pointer_cast(iter)->Clear(); + if (auto mutableIter = AZStd::const_pointer_cast(iter)) + { + mutableIter->Clear(); + } } m_functions.clear(); @@ -155,24 +158,36 @@ namespace ScriptCanvas for (auto iter : m_ebusHandlingByNode) { - iter.second->Clear(); + if (iter.second) + { + iter.second->Clear(); + } } m_ebusHandlingByNode.clear(); for (auto iter : m_eventHandlingByNode) { - iter.second->Clear(); + if (iter.second) + { + iter.second->Clear(); + } } for (auto iter : m_nodeablesByNode) { - AZStd::const_pointer_cast(iter.second)->Clear(); + if (auto mutableIter = AZStd::const_pointer_cast(iter.second)) + { + mutableIter->Clear(); + } } m_nodeablesByNode.clear(); for (auto iter : m_variableWriteHandlingBySlot) { - AZStd::const_pointer_cast(iter.second)->Clear(); + if (auto mutableIter = AZStd::const_pointer_cast(iter.second)) + { + mutableIter->Clear(); + } } m_variableWriteHandlingBySlot.clear(); m_variableWriteHandlingByVariable.clear(); @@ -795,13 +810,6 @@ namespace ScriptCanvas } } - AZ_Assert(variables.size() == constructionNodeables.size() + constructionInputVariables.size() + entityIds.size() - , "ctor var size: %zu, nodeables: %zu, inputs: %zu, entity ids: %zu" - , variables.size() - , constructionNodeables.size() - , constructionInputVariables.size() - , entityIds.size()); - return variables; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp index bbde312ef3..672375f29b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp @@ -82,7 +82,10 @@ namespace ScriptCanvas { for (auto& iter : m_events) { - AZStd::const_pointer_cast(iter.second)->Clear(); + if (auto event = AZStd::const_pointer_cast(iter.second)) + { + event->Clear(); + } } } @@ -90,7 +93,10 @@ namespace ScriptCanvas { m_eventNode = nullptr; m_eventSlot = nullptr; - AZStd::const_pointer_cast(m_eventHandlerFunction)->Clear(); + if (auto function = AZStd::const_pointer_cast(m_eventHandlerFunction)) + { + function->Clear(); + } } void FunctionPrototype::Clear() @@ -152,7 +158,10 @@ namespace ScriptCanvas for (auto& iter : m_latents) { - AZStd::const_pointer_cast(iter.second)->Clear(); + if (auto latent = AZStd::const_pointer_cast(iter.second)) + { + latent->Clear(); + } } m_latents.clear(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp index c6e7925a31..ed61d7e838 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesExecution.cpp @@ -72,7 +72,10 @@ namespace ScriptCanvas for (auto returnValue : m_returnValues) { - AZStd::const_pointer_cast(returnValue.second)->Clear(); + if (auto returnValuePtr = AZStd::const_pointer_cast(returnValue.second)) + { + returnValuePtr->Clear(); + } } m_returnValues.clear(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index 1a69dbb25e..0e0467fdcc 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -249,22 +249,48 @@ namespace ScriptCanvas return; } - if (className.empty()) + if (!InitializeOverloaded(namespaces, className, methodName)) { - InitializeFree(namespaces, methodName); - } - else if (auto ebusIterator = behaviorContext->m_ebuses.find(className); ebusIterator == behaviorContext->m_ebuses.end()) - { - InitializeClass(namespaces, className, methodName); - } - else - { - InitializeEvent(namespaces, className, methodName); + if (className.empty()) + { + InitializeFree(namespaces, methodName); + } + else if (auto ebusIterator = behaviorContext->m_ebuses.find(className); ebusIterator == behaviorContext->m_ebuses.end()) + { + InitializeClass(namespaces, className, methodName); + } + else + { + InitializeEvent(namespaces, className, methodName); + } } PopulateNodeType(); } + bool Method::InitializeOverloaded([[maybe_unused]] const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName) + { + const AZ::BehaviorMethod* method{}; + const AZ::BehaviorClass* bcClass{}; + AZStd::string prettyClassName; + + if (IsMethodOverloaded() && BehaviorContextUtils::FindExplicitOverload(method, bcClass, className, methodName, &prettyClassName)) + { + MethodConfiguration config(*method, method->IsMember() ? MethodType::Member : MethodType::Free); + config.m_class = bcClass; + config.m_namespaces = &m_namespaces; + config.m_className = &className; + config.m_lookupName = &methodName; + config.m_prettyClassName = prettyClassName; + InitializeMethod(config); + return true; + } + else + { + return false; + } + } + void Method::InitializeClass(const NamespacePath&, AZStd::string_view className, AZStd::string_view methodName) { AZStd::lock_guard lock(m_mutex); @@ -273,8 +299,7 @@ namespace ScriptCanvas const AZ::BehaviorClass* bcClass{}; AZStd::string prettyClassName; - if ((IsMethodOverloaded() && BehaviorContextUtils::FindExplicitOverload(method, bcClass, className, methodName, &prettyClassName)) - || BehaviorContextUtils::FindClass(method, bcClass, className, methodName, &prettyClassName)) + if (BehaviorContextUtils::FindClass(method, bcClass, className, methodName, &prettyClassName)) { MethodConfiguration config(*method, MethodType::Member); config.m_class = bcClass; @@ -308,6 +333,7 @@ namespace ScriptCanvas AZStd::lock_guard lock(m_mutex); const AZ::BehaviorMethod* method{}; + if (BehaviorContextUtils::FindFree(method, methodName)) { MethodConfiguration config(*method, MethodType::Free); @@ -525,6 +551,17 @@ namespace ScriptCanvas m_method = &method; m_class = bcClass; + AZ::BehaviorContext* behaviorContext = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext); + + if (bcClass && behaviorContext) + { + if (auto prettyNameAttribute = AZ::FindAttribute(AZ::ScriptCanvasAttributes::PrettyName, bcClass->m_attributes)) + { + AZ::AttributeReader operatorAttrReader(nullptr, prettyNameAttribute); + operatorAttrReader.Read(m_classNamePretty, *behaviorContext); + } + } if (m_classNamePretty.empty()) { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h index 7af2c15e82..b03e3aefd8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.h @@ -86,8 +86,6 @@ namespace ScriptCanvas bool IsObjectClass(AZStd::string_view objectClass) const { return objectClass.compare(m_className) == 0; } - - //! Attempts to initialize node with a BehaviorContext BehaviorMethod //! If the className is empty, then the methodName is searched on the BehaviorContext //! If className is not empty the className is used to look for a registered BehaviorEBus in the BehaviorContext @@ -102,6 +100,8 @@ namespace ScriptCanvas void InitializeFree(const NamespacePath& namespaces, AZStd::string_view methodName); + bool InitializeOverloaded(const NamespacePath& namespaces, AZStd::string_view className, AZStd::string_view methodName); + AZ_INLINE bool IsValid() const { return m_method != nullptr; } bool HasBusID() const { return (m_method == nullptr) ? false : m_method->HasBusId(); }