diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index 73e18a356c..9c3cdca3e8 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -31,29 +31,42 @@ namespace ScriptCanvasBuilder m_source.Reset(); m_variables.clear(); m_overrides.clear(); + m_overridesUnused.clear(); m_entityIds.clear(); m_dependencies.clear(); } void BuildVariableOverrides::CopyPreviousOverriddenValues(const BuildVariableOverrides& source) { - for (auto& overriddenValue : m_overrides) + auto copyPreviousIfFound = [](ScriptCanvas::GraphVariable& overriddenValue, const AZStd::vector& source) { - auto iter = AZStd::find_if(source.m_overrides.begin(), source.m_overrides.end(), [&overriddenValue](const auto& candidate) { return candidate.GetVariableId() == overriddenValue.GetVariableId(); }); - - if (iter != source.m_overrides.end()) + if (auto iter = AZStd::find_if(source.begin(), source.end(), [&overriddenValue](const auto& candidate) { return candidate.GetVariableId() == overriddenValue.GetVariableId(); }); + iter != source.end()) { overriddenValue.DeepCopy(*iter); overriddenValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); overriddenValue.SetAllowSignalOnChange(false); - // check that a name update is not necessary anymore + return true; + } + else + { + return false; + } + }; + + for (auto& overriddenValue : m_overrides) + { + if (!copyPreviousIfFound(overriddenValue, source.m_overrides)) + { + // the variable in question may have been previously unused, and is now used, so copy the previous value over + copyPreviousIfFound(overriddenValue, source.m_overridesUnused); } } ////////////////////////////////////////////////////////////////////////// // #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one. // the above will provide the data to handle the cases where only certain dependency nodes were removed - // until then we do a sanity check, if any part of the depenecies were altered, assume no overrides are valid. + // until then we do a sanity check, if any part of the dependencies were altered, assume no overrides are valid. if (m_dependencies.size() != source.m_dependencies.size()) { return; @@ -86,31 +99,41 @@ namespace ScriptCanvasBuilder if (auto serializeContext = azrtti_cast(reflectContext)) { serializeContext->Class() - ->Version(0) + ->Version(1) ->Field("source", &BuildVariableOverrides::m_source) ->Field("variables", &BuildVariableOverrides::m_variables) ->Field("entityId", &BuildVariableOverrides::m_entityIds) ->Field("overrides", &BuildVariableOverrides::m_overrides) + ->Field("overridesUnused", &BuildVariableOverrides::m_overridesUnused) ->Field("dependencies", &BuildVariableOverrides::m_dependencies) ; if (auto editContext = serializeContext->GetEditContext()) { - editContext->Class< BuildVariableOverrides>("Variables", "Variables exposed by the attached Script Canvas Graph") - ->ClassElement(AZ::Edit::ClassElements::Group, "Variable Fields") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + editContext->Class("Variables", "Variables exposed by the attached Script Canvas Graph") ->DataElement(AZ::Edit::UIHandlers::Default, &BuildVariableOverrides::m_overrides, "Variables", "Array of Variables within Script Canvas Graph") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) + ->DataElement(AZ::Edit::UIHandlers::Default, &BuildVariableOverrides::m_overridesUnused, "Unused Variables", "Unused variables within Script Canvas Graph, when used they keep the values set here") + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) ->DataElement(AZ::Edit::UIHandlers::Default, &BuildVariableOverrides::m_dependencies, "Dependencies", "Variables in Dependencies of the Script Canvas Graph") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) ; } } } // use this to initialize the new data, and make sure they have a editor graph variable for proper editor display - void BuildVariableOverrides::PopulateFromParsedResults(const ScriptCanvas::Grammar::ParsedRuntimeInputs& inputs, const ScriptCanvas::VariableData& variables) + void BuildVariableOverrides::PopulateFromParsedResults(ScriptCanvas::Grammar::AbstractCodeModelConstPtr abstractCodeModel, const ScriptCanvas::VariableData& variables) { + if (!abstractCodeModel) + { + AZ_Error("ScriptCanvasBuider", false, "null abstract code model"); + return; + } + + const ScriptCanvas::Grammar::ParsedRuntimeInputs& inputs = abstractCodeModel->GetRuntimeInputs(); + for (auto& variable : inputs.m_variables) { auto graphVariable = variables.FindVariable(variable.first); @@ -148,6 +171,23 @@ namespace ScriptCanvasBuilder } } } + + for (auto& variable : abstractCodeModel->GetVariablesUnused()) + { + auto graphVariable = variables.FindVariable(variable->m_sourceVariableId); + if (!graphVariable) + { + AZ_Error("ScriptCanvasBuilder", false, "Missing Variable from graph data that was just parsed"); + continue; + } + + // copy to override unused list for editor display + m_overridesUnused.push_back(*graphVariable); + auto& overrideValue = m_overridesUnused.back(); + overrideValue.DeepCopy(*graphVariable); + overrideValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); + overrideValue.SetAllowSignalOnChange(false); + } } EditorAssetTree* EditorAssetTree::ModRoot() @@ -346,7 +386,7 @@ namespace ScriptCanvasBuilder BuildVariableOverrides result; result.m_source = editorAssetTree.m_asset; - result.PopulateFromParsedResults(parseOutcome.GetValue()->GetRuntimeInputs(), *variableData); + result.PopulateFromParsedResults(parseOutcome.GetValue(), *variableData); // recurse... for (auto& dependentAsset : editorAssetTree.m_dependencies) @@ -356,7 +396,7 @@ namespace ScriptCanvasBuilder if (!parseDependentOutcome.IsSuccess()) { return AZ::Failure(AZStd::string::format - ("ParseEditorAssetTree failed to parse dependent graph from %s-%s: %s" + ( "ParseEditorAssetTree failed to parse dependent graph from %s-%s: %s" , dependentAsset.m_asset.GetId().ToString().c_str() , dependentAsset.m_asset.GetHint().c_str() , parseDependentOutcome.GetError().c_str())); diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h index c5478b51f4..f03e78bc3e 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h @@ -10,16 +10,9 @@ #include #include +#include #include -namespace ScriptCanvas -{ - namespace Grammar - { - struct ParsedRuntimeInputs; - } -} - namespace ScriptCanvasEditor { class ScriptCanvasAsset; @@ -43,7 +36,7 @@ namespace ScriptCanvasBuilder bool IsEmpty() const; // use this to initialize the new data, and make sure they have a editor graph variable for proper editor display - void PopulateFromParsedResults(const ScriptCanvas::Grammar::ParsedRuntimeInputs& inputs, const ScriptCanvas::VariableData& variables); + void PopulateFromParsedResults(ScriptCanvas::Grammar::AbstractCodeModelConstPtr abstractCodeModel, const ScriptCanvas::VariableData& variables); // #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one. AZ::Data::Asset m_source; @@ -52,8 +45,9 @@ namespace ScriptCanvasBuilder AZStd::vector m_variables; // the values here may or may not be overrides AZStd::vector> m_entityIds; - // this is all that gets exposed to the edit context + // these two variable lists are all that gets exposed to the edit context AZStd::vector m_overrides; + AZStd::vector m_overridesUnused; // AZStd::vector m_entityIdRuntimeInputIndices; since all of the entity ids need to go in, they may not need indices AZStd::vector m_dependencies; }; diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h index 6bd5caf1a6..668e1a0bcd 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h @@ -58,6 +58,7 @@ namespace ScriptCanvasBuilder AddAssetDependencySearch, PrefabIntegration, CorrectGraphVariableVersion, + ReflectEntityIdNodes, // add new entries above Current, }; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 3e4a425a6e..4509e7e907 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -1358,17 +1358,23 @@ namespace ScriptCanvas { if (variable->m_isMember) { - return !this->m_variableUse.memberVariables.contains(variable); + if (!this->m_variableUse.memberVariables.contains(variable)) + { + m_variablesUnused.push_back(variable); + return true; + } } else { - return !this->m_variableUse.localVariables.contains(variable); + if (!this->m_variableUse.localVariables.contains(variable)) + { + m_variablesUnused.push_back(variable); + return true; + } } } - else - { - return false; - } + + return false; }); } @@ -2068,6 +2074,11 @@ namespace ScriptCanvas return m_variables; } + const AZStd::vector& AbstractCodeModel::GetVariablesUnused() const + { + return m_variablesUnused; + } + bool AbstractCodeModel::IsActiveGraph() const { if (!m_nodeablesByNode.empty()) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index cdbdf611e5..7c5340bd18 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -138,6 +138,8 @@ namespace ScriptCanvas const AZStd::vector& GetVariables() const; + const AZStd::vector& GetVariablesUnused() const; + bool IsErrorFree() const; // has modified data or handlers @@ -166,8 +168,6 @@ namespace ScriptCanvas void AddAllVariablesPreParse(); - void AddAllVariablesPreParse_LegacyFunctions(); - void AddDebugInformation(); void AddDebugInformation(ExecutionChild& execution); @@ -519,6 +519,7 @@ namespace ScriptCanvas AZStd::unordered_map m_dependencyByVariable; AZStd::vector m_variables; + AZStd::vector m_variablesUnused; AZStd::vector m_possibleExecutionRoots; // true iff there are no internal errors and no error validation events