From dcb3c71d33b5f2aae30d8ed64575fcf1c751b939 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 29 Jun 2021 13:25:56 -0700 Subject: [PATCH 01/16] Initial prefab integration Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Asset/EditorAssetSystemComponent.cpp | 12 +- .../Asset/RuntimeAssetSystemComponent.cpp | 6 +- .../Code/Builder/ScriptCanvasBuilder.cpp | 372 ++++++++++++++++++ .../Code/Builder/ScriptCanvasBuilder.h | 82 ++++ .../Builder/ScriptCanvasBuilderComponent.cpp | 3 + .../Builder/ScriptCanvasBuilderWorker.cpp | 11 +- .../Code/Builder/ScriptCanvasBuilderWorker.h | 12 +- .../ScriptCanvasBuilderWorkerUtility.cpp | 46 ++- .../EditorScriptCanvasComponent.cpp | 245 +++--------- .../Framework/ScriptCanvasGraphUtilities.h | 16 +- .../Framework/ScriptCanvasGraphUtilities.inl | 52 ++- .../Components/EditorScriptCanvasComponent.h | 32 +- .../LoggingPanel/LoggingDataAggregator.cpp | 8 +- .../ScriptCanvas/Asset/RuntimeAsset.cpp | 99 ++++- .../Include/ScriptCanvas/Asset/RuntimeAsset.h | 29 +- .../Code/Include/ScriptCanvas/Core/Core.cpp | 32 +- .../Code/Include/ScriptCanvas/Core/Core.h | 43 +- .../Code/Include/ScriptCanvas/Core/Datum.cpp | 363 +++++++++-------- .../Code/Include/ScriptCanvas/Core/Datum.h | 24 +- .../Code/Include/ScriptCanvas/Core/Graph.cpp | 48 +-- .../ScriptCanvas/Debugger/Debugger.cpp | 3 +- .../Execution/ExecutionContext.cpp | 125 +++--- .../ScriptCanvas/Execution/ExecutionContext.h | 22 +- .../ScriptCanvas/Execution/ExecutionState.cpp | 30 +- .../ScriptCanvas/Execution/ExecutionState.h | 10 +- .../Interpreted/ExecutionInterpretedAPI.cpp | 50 ++- .../Interpreted/ExecutionStateInterpreted.cpp | 24 +- ...ExecutionStateInterpretedPerActivation.cpp | 17 +- .../ExecutionStateInterpretedPure.cpp | 10 +- .../Execution/RuntimeComponent.cpp | 66 ++-- .../ScriptCanvas/Execution/RuntimeComponent.h | 25 +- .../Grammar/AbstractCodeModel.cpp | 308 ++++++++------- .../ScriptCanvas/Grammar/AbstractCodeModel.h | 35 +- .../ScriptCanvas/Grammar/ParsingUtilities.cpp | 48 ++- .../ScriptCanvas/Grammar/ParsingUtilities.h | 13 +- .../ScriptCanvas/Grammar/Primitives.cpp | 39 +- .../Grammar/PrimitivesDeclarations.cpp | 8 +- .../Grammar/PrimitivesDeclarations.h | 22 +- .../ScriptUserDataSerializer.cpp | 104 +++++ .../Serialization/ScriptUserDataSerializer.h | 36 ++ .../ScriptCanvas/Translation/GraphToX.cpp | 16 +- .../ScriptCanvas/Translation/Translation.cpp | 86 ++-- .../ScriptCanvas/Translation/Translation.h | 15 +- .../Translation/TranslationResult.h | 18 +- .../Translation/TranslationUtilities.cpp | 2 +- .../Translation/TranslationUtilities.h | 2 +- .../ScriptCanvas/Variable/GraphVariable.cpp | 72 ++-- .../Code/Source/SystemComponent.cpp | 26 +- .../Code/scriptcanvasgem_common_files.cmake | 4 +- ...scriptcanvasgem_editor_builder_files.cmake | 4 +- 50 files changed, 1764 insertions(+), 1011 deletions(-) create mode 100644 Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp create mode 100644 Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp create mode 100644 Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp index 69c8032d1f..b59c02f0b6 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -19,7 +19,7 @@ #include #include -// Undo this + // Undo this AZ_PUSH_DISABLE_WARNING(4251 4800 4244, "-Wunknown-warning-option") #include #include @@ -90,8 +90,8 @@ namespace ScriptCanvasEditor void EditorAssetSystemComponent::Deactivate() { ScriptCanvas::Translation::RequestBus::Handler::BusDisconnect(); - ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); - + ScriptCanvas::Grammar::RequestBus::Handler::BusDisconnect(); + EditorAssetConversionBus::Handler::BusDisconnect(); AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); m_editorAssetRegistry.Unregister(); @@ -119,8 +119,8 @@ namespace ScriptCanvasEditor AZ::Data::Asset EditorAssetSystemComponent::LoadAsset(AZStd::string_view graphPath) { - auto outcome = ScriptCanvasBuilder::LoadEditorAsset(graphPath); - + auto outcome = ScriptCanvasBuilder::LoadEditorAsset(graphPath, AZ::Data::AssetId(AZ::Uuid::CreateRandom())); + if (outcome.IsSuccess()) { return outcome.GetValue(); diff --git a/Gems/ScriptCanvas/Code/Asset/RuntimeAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/RuntimeAssetSystemComponent.cpp index e15a2ae955..128a2f1915 100644 --- a/Gems/ScriptCanvas/Code/Asset/RuntimeAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/RuntimeAssetSystemComponent.cpp @@ -21,8 +21,10 @@ namespace ScriptCanvas void RuntimeAssetSystemComponent::Reflect(AZ::ReflectContext* context) { - ScriptCanvas::RuntimeData::Reflect(context); - ScriptCanvas::SubgraphInterfaceData::Reflect(context); + RuntimeData::Reflect(context); + RuntimeDataOverrides::Reflect(context); + SubgraphInterfaceData::Reflect(context); + if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp new file mode 100644 index 0000000000..ff0fdf6273 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -0,0 +1,372 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include +#include + +namespace ScriptCanvasBuilderCpp +{ + void AppendTabs(AZStd::string& result, size_t depth) + { + for (size_t i = 0; i < depth; ++i) + { + result += "\t"; + } + } +} + +namespace ScriptCanvasBuilder +{ + void BuildVariableOverrides::Clear() + { + m_source.Reset(); + m_variables.clear(); + m_entityIds.clear(); + m_dependencies.clear(); + } + + void BuildVariableOverrides::CopyPreviousOverriddenValues(const BuildVariableOverrides& source) + { + for (auto& overriddenValue : m_overrides) + { + 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()) + { + overriddenValue.DeepCopy(*iter); + overriddenValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); + overriddenValue.SetAllowSignalOnChange(false); + // check that a name update is not necessary anymore + } + } + + ////////////////////////////////////////////////////////////////////////// + // #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. + if (m_dependencies.size() != source.m_dependencies.size()) + { + return; + } + else + { + for (size_t index = 0; index != m_dependencies.size(); ++index) + { + if (m_dependencies[index].m_source != source.m_dependencies[index].m_source) + { + return; + } + } + } + ////////////////////////////////////////////////////////////////////////// + + for (size_t index = 0; index != m_dependencies.size(); ++index) + { + m_dependencies[index].CopyPreviousOverriddenValues(source.m_dependencies[index]); + } + } + + bool BuildVariableOverrides::IsEmpty() const + { + return m_variables.empty() && m_entityIds.empty() && m_dependencies.empty(); + } + + void BuildVariableOverrides::Reflect(AZ::ReflectContext* reflectContext) + { + if (auto serializeContext = azrtti_cast(reflectContext)) + { + serializeContext->Class() + ->Version(0) + ->Field("source", &BuildVariableOverrides::m_source) + ->Field("variables", &BuildVariableOverrides::m_variables) + ->Field("entityId", &BuildVariableOverrides::m_entityIds) + ->Field("overrides", &BuildVariableOverrides::m_overrides) + ->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) + ->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) + ->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) + ; + } + } + } + + // 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) + { + for (auto& variable : inputs.m_variables) + { + auto graphVariable = variables.FindVariable(variable.first); + if (!graphVariable) + { + AZ_Error("ScriptCanvasBuilder", false, "Missing Variable from graph data that was just parsed"); + continue; + } + + m_variables.push_back(*graphVariable); + auto& buildVariable = m_variables.back(); + buildVariable.DeepCopy(*graphVariable); // in case of BCO, a new one needs to be created + + // copy to override list for editor display + m_overrides.push_back(*graphVariable); + auto& overrideValue = m_overrides.back(); + overrideValue.DeepCopy(*graphVariable); + overrideValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); + overrideValue.SetAllowSignalOnChange(false); + } + + for (auto& entityId : inputs.m_entityIds) + { + m_entityIds.push_back(entityId); + + if (!ScriptCanvas::Grammar::IsParserGeneratedId(entityId.first)) + { + auto graphEntityId = variables.FindVariable(entityId.first); + if (!graphEntityId) + { + AZ_Error("ScriptCanvasBuilder", false, "Missing EntityId from graph data that was just parsed"); + continue; + } + + // copy to override list for editor display + if (graphEntityId->IsComponentProperty()) + { + m_overrides.push_back(*graphEntityId); + auto& overrideValue = m_overrides.back(); + overrideValue.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); + overrideValue.SetAllowSignalOnChange(false); + } + } + } + } + + EditorAssetTree* EditorAssetTree::ModRoot() + { + if (!m_parent) + { + return this; + } + + return m_parent->ModRoot(); + } + + void EditorAssetTree::SetParent(EditorAssetTree& parent) + { + m_parent = &parent; + } + + AZStd::string EditorAssetTree::ToString(size_t depth) const + { + AZStd::string result; + ScriptCanvasBuilderCpp::AppendTabs(result, depth); + result += m_asset.GetId().ToString(); + result += m_asset.GetHint(); + depth += m_dependencies.empty() ? 0 : 1; + + for (const auto& dependency : m_dependencies) + { + result += "\n"; + ScriptCanvasBuilderCpp::AppendTabs(result, depth); + result += dependency.ToString(depth); + } + + return result; + } + + ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& buildOverrides) + { + ScriptCanvas::RuntimeDataOverrides runtimeOverrides; + + runtimeOverrides.m_runtimeAsset = AZ::Data::Asset + (AZ::Data::AssetId(buildOverrides.m_source.GetId().m_guid, AZ_CRC("RuntimeData", 0x163310ae)), azrtti_typeid(), {}); + runtimeOverrides.m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); + runtimeOverrides.m_variableIndices.resize(buildOverrides.m_variables.size()); + + for (size_t index = 0; index != buildOverrides.m_variables.size(); ++index) + { + auto& variable = buildOverrides.m_variables[index]; + auto iter = AZStd::find_if(buildOverrides.m_overrides.begin(), buildOverrides.m_overrides.end(), [&variable](auto& candidate) { return candidate.GetVariableId() == variable.GetVariableId(); }); + if (iter != buildOverrides.m_overrides.end()) + { + if (iter->GetDatum()) + { + runtimeOverrides.m_variables.push_back(ScriptCanvas::RuntimeVariable(iter->GetDatum()->ToAny())); + runtimeOverrides.m_variableIndices[index] = true; + } + else + { + AZ_Warning("ScriptCanvasBuilder", false, "build overrides missing variable override, Script may not function properly"); + runtimeOverrides.m_variableIndices[index] = false; + } + } + else + { + runtimeOverrides.m_variableIndices[index] = false; + } + } + + for (auto& entity : buildOverrides.m_entityIds) + { + auto& variableId = entity.first; + auto iter = AZStd::find_if(buildOverrides.m_overrides.begin(), buildOverrides.m_overrides.end(), [&variableId](auto& candidate) { return candidate.GetVariableId() == variableId; }); + if (iter != buildOverrides.m_overrides.end()) + { + // the entity was overridden on the instance + if (iter->GetDatum() && iter->GetDatum()->GetAs()) + { + runtimeOverrides.m_entityIds.push_back(*iter->GetDatum()->GetAs()); + } + else + { + AZ_Warning("ScriptCanvasBuilder", false, "build overrides missing EntityId, Script may not function properly"); + runtimeOverrides.m_entityIds.push_back(AZ::EntityId{}); + } + } + else + { + // the entity is overridden, as part of the required process of to instantiation + runtimeOverrides.m_entityIds.push_back(entity.second); + } + } + + for (auto& buildDependency : buildOverrides.m_dependencies) + { + runtimeOverrides.m_dependencies.push_back(ConvertToRuntime(buildDependency)); + } + + return runtimeOverrides; + } + + AZ::Outcome LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent) + { + EditorAssetTree result; + AZ::Data::AssetInfo assetInfo; + AZStd::string watchFolder; + bool resultFound = false; + + if (!AzToolsFramework::AssetSystemRequestBus::FindFirstHandler()) + { + return AZ::Failure(AZStd::string("LoadEditorAssetTree found no handler for AzToolsFramework::AssetSystemRequestBus.")); + } + + AzToolsFramework::AssetSystemRequestBus::BroadcastResult + (resultFound + , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourceUUID + , editorAssetId.m_guid + , assetInfo + , watchFolder); + + if (!resultFound) + { + return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%s.", editorAssetId.ToString().c_str(), assetHint.data())); + } + + AZStd::vector dependentAssets; + + auto filterCB = [&dependentAssets](const AZ::Data::AssetFilterInfo& filterInfo)->bool + { + if (filterInfo.m_assetType == azrtti_typeid()) + { + dependentAssets.push_back(AZ::Data::AssetId(filterInfo.m_assetId.m_guid, 0)); + } + else if (filterInfo.m_assetType == azrtti_typeid()) + { + dependentAssets.push_back(filterInfo.m_assetId); + } + + return true; + }; + + auto loadAssetOutcome = ScriptCanvasBuilder::LoadEditorAsset(assetInfo.m_relativePath, editorAssetId, filterCB); + if (!loadAssetOutcome.IsSuccess()) + { + return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load graph from %s-%s: %s", editorAssetId.ToString().c_str(), assetHint.data(), loadAssetOutcome.GetError().c_str())); + } + + for (auto& dependentAsset : dependentAssets) + { + auto loadDependentOutcome = LoadEditorAssetTree(dependentAsset, "", &result); + if (!loadDependentOutcome.IsSuccess()) + { + return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to load dependent graph from %s-%s: %s", editorAssetId.ToString().c_str(), assetHint.data(), loadDependentOutcome.GetError().c_str())); + } + + result.m_dependencies.push_back(loadDependentOutcome.TakeValue()); + } + + if (parent) + { + result.SetParent(*parent); + } + + result.m_asset = loadAssetOutcome.TakeValue(); + + return AZ::Success(result); + } + + AZ::Outcome ParseEditorAssetTree(const EditorAssetTree& editorAssetTree) + { + auto buildEntity = editorAssetTree.m_asset->GetScriptCanvasEntity(); + if (!buildEntity) + { + return AZ::Failure(AZStd::string("No entity from source asset")); + } + + auto variableComponent = AZ::EntityUtils::FindFirstDerivedComponent(buildEntity); + if (!variableComponent) + { + return AZ::Failure(AZStd::string("No GraphVariableManagerComponent in source Entity")); + } + + const ScriptCanvas::VariableData* variableData = variableComponent->GetVariableDataConst(); // get this from the entity + if (!variableData) + { + return AZ::Failure(AZStd::string("No variableData in source GraphVariableManagerComponent")); + } + + auto parseOutcome = ScriptCanvasBuilder::ParseGraph(*buildEntity, ""); + if (!parseOutcome.IsSuccess() || !parseOutcome.GetValue()) + { + return AZ::Failure(AZStd::string("graph failed to parse")); + } + + BuildVariableOverrides result; + result.m_source = editorAssetTree.m_asset; + result.PopulateFromParsedResults(parseOutcome.GetValue()->GetRuntimeInputs(), *variableData); + + // recurse... + for (auto& dependentAsset : editorAssetTree.m_dependencies) + { + // #functions2 provide an identifier for the node/variable in the source that caused the dependency. the root will not have one. + auto parseDependentOutcome = ParseEditorAssetTree(dependentAsset); + if (!parseDependentOutcome.IsSuccess()) + { + return AZ::Failure(AZStd::string::format + ("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())); + } + + result.m_dependencies.push_back(parseDependentOutcome.TakeValue()); + } + + return AZ::Success(result); + } + +} diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h new file mode 100644 index 0000000000..ea77b4c9b0 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace ScriptCanvas +{ + namespace Grammar + { + struct ParsedRuntimeInputs; + } +} + +namespace ScriptCanvasEditor +{ + class ScriptCanvasAsset; +} + +namespace ScriptCanvasBuilder +{ + class BuildVariableOverrides + { + public: + AZ_TYPE_INFO(BuildVariableOverrides, "{8336D44C-8EDC-4C28-AEB4-3420D5FD5AE2}"); + AZ_CLASS_ALLOCATOR(BuildVariableOverrides, AZ::SystemAllocator, 0); + + static void Reflect(AZ::ReflectContext* reflectContext); + + void Clear(); + + // use this to preserve old values that may have been overridden on the instance, and are still valid in the parsed graph + void CopyPreviousOverriddenValues(const BuildVariableOverrides& source); + + 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); + + // #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; + + // all of the variables here are overrides + 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 + AZStd::vector m_overrides; + // AZStd::vector m_entityIdRuntimeInputIndices; since all of the entity ids need to go in, they may not need indices + AZStd::vector m_dependencies; + }; + + class EditorAssetTree + { + public: + AZ_CLASS_ALLOCATOR(EditorAssetTree, AZ::SystemAllocator, 0); + + EditorAssetTree* m_parent = nullptr; + AZStd::vector m_dependencies; + AZ::Data::Asset m_asset; + + EditorAssetTree* ModRoot(); + + void SetParent(EditorAssetTree& parent); + + AZStd::string ToString(size_t depth = 0) const; + }; + + // copy the variables overridden during editor / prefab build time back to runtime data + ScriptCanvas::RuntimeDataOverrides ConvertToRuntime(const BuildVariableOverrides& overrides); + + AZ::Outcome LoadEditorAssetTree(AZ::Data::AssetId editorAssetId, AZStd::string_view assetHint, EditorAssetTree* parent = nullptr); + + AZ::Outcome ParseEditorAssetTree(const EditorAssetTree& editorAssetTree); +} diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp index cd7540c663..269c033dd9 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderComponent.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -163,6 +164,8 @@ namespace ScriptCanvasBuilder void PluginComponent::Reflect(AZ::ReflectContext* context) { + BuildVariableOverrides::Reflect(context); + if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp index 2284ba94cf..1c6fc3f2db 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -70,6 +70,7 @@ namespace ScriptCanvasBuilder AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data()); return; } + AZStd::vector fileBuffer(ioStream.GetLength()); size_t bytesRead = ioStream.Read(fileBuffer.size(), fileBuffer.data()); if (bytesRead != ioStream.GetLength()) @@ -87,15 +88,15 @@ namespace ScriptCanvasBuilder { // force load these before processing if (filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid()) + || filterInfo.m_assetType == azrtti_typeid()) { this->m_processEditorAssetDependencies.push_back(filterInfo); } // these trigger re-processing if (filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid()) + || filterInfo.m_assetType == azrtti_typeid() + || filterInfo.m_assetType == azrtti_typeid()) { AssetBuilderSDK::SourceFileDependency dependency; dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid; @@ -210,7 +211,7 @@ namespace ScriptCanvasBuilder bool pathFound = false; AZStd::string relativePath; AzToolsFramework::AssetSystemRequestBus::BroadcastResult - ( pathFound + (pathFound , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath , request.m_fullPath.c_str(), relativePath); diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h index 4ef20f5fb1..90dfb843b9 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -130,10 +130,12 @@ namespace ScriptCanvasBuilder int GetBuilderVersion(); - AZ::Outcome, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath); + AZ::Outcome, AZStd::string> LoadEditorAsset(AZStd::string_view graphPath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB = {}); AZ::Outcome, AZStd::string> LoadEditorFunctionAsset(AZStd::string_view graphPath); + AZ::Outcome ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath); + AZ::Outcome ProcessTranslationJob(ProcessTranslationJobInput& input); ScriptCanvasEditor::Graph* PrepareSourceGraph(AZ::Entity* const buildEntity); @@ -149,7 +151,7 @@ namespace ScriptCanvasBuilder { public: static AZ::Uuid GetUUID(); - + Worker() = default; Worker(const Worker&) = delete; @@ -175,7 +177,7 @@ namespace ScriptCanvasBuilder // cached on first time query mutable AZStd::string m_fingerprintString; }; - + class FunctionWorker : public AssetBuilderSDK::AssetBuilderCommandBus::Handler { @@ -195,7 +197,7 @@ namespace ScriptCanvasBuilder int GetVersionNumber() const; void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const; - + void ShutDown() override {}; private: diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp index 375b217780..529a611c67 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -17,9 +17,7 @@ #include #include #include - #include - #include #include #include @@ -32,7 +30,6 @@ #include #include #include - #include namespace ScriptCanvasBuilder @@ -62,6 +59,26 @@ namespace ScriptCanvasBuilder } } + AZ::Outcome ParseGraph(AZ::Entity& buildEntity, AZStd::string_view graphPath) + { + AZStd::string fileNameOnly; + AzFramework::StringFunc::Path::GetFullFileName(graphPath.data(), fileNameOnly); + + ScriptCanvas::Grammar::Request request; + request.graph = PrepareSourceGraph(&buildEntity); + if (!request.graph) + { + return AZ::Failure(AZStd::string("build entity did not have source graph components")); + } + + request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFileAtPrefabTime; + request.printModelToConsole = ScriptCanvas::Grammar::g_printAbstractCodeModelAtPrefabTime; + request.name = fileNameOnly.empty() ? fileNameOnly : "BuilderGraph"; + request.addDebugInformation = false; + + return ScriptCanvas::Translation::ParseGraph(request); + } + AZ::Outcome CreateLuaAsset(AZ::Entity* buildEntity, AZ::Data::AssetId scriptAssetId, AZStd::string_view rawLuaFilePath) { AZStd::string fullPath(rawLuaFilePath); @@ -72,7 +89,7 @@ namespace ScriptCanvasBuilder auto sourceGraph = PrepareSourceGraph(buildEntity); ScriptCanvas::Grammar::Request request; - request.assetId = scriptAssetId; + request.scriptAssetId = scriptAssetId; request.graph = sourceGraph; request.name = fileNameOnly; request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile; @@ -82,7 +99,7 @@ namespace ScriptCanvasBuilder bool pathFound = false; AZStd::string relativePath; AzToolsFramework::AssetSystemRequestBus::BroadcastResult - ( pathFound + (pathFound , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath , fullPath.c_str(), relativePath); @@ -396,7 +413,7 @@ namespace ScriptCanvasBuilder ; } - AZ::Outcome < AZ::Data::Asset, AZStd::string> LoadEditorAsset(AZStd::string_view filePath) + AZ::Outcome < AZ::Data::Asset, AZStd::string> LoadEditorAsset(AZStd::string_view filePath, AZ::Data::AssetId assetId, AZ::Data::AssetFilterCB assetFilterCB) { AZStd::shared_ptr assetDataStream = AZStd::make_shared(); @@ -425,9 +442,9 @@ namespace ScriptCanvasBuilder AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); AZ::Data::Asset asset; - asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom())); + asset.Create(assetId); - if (editorAssetHandler.LoadAssetData(asset, assetDataStream, AZ::Data::AssetFilterCB{}) != AZ::Data::AssetHandler::LoadResult::LoadComplete) + if (editorAssetHandler.LoadAssetData(asset, assetDataStream, assetFilterCB) != AZ::Data::AssetHandler::LoadResult::LoadComplete) { return AZ::Failure(AZStd::string::format("Failed to load ScriptCavas asset: %s", filePath.data())); } @@ -513,10 +530,7 @@ namespace ScriptCanvasBuilder } } - if (buildEntity->GetState() == AZ::Entity::State::Constructed) - { - buildEntity->Init(); - } + ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(buildEntity); if (buildEntity->GetState() == AZ::Entity::State::Init) { @@ -533,7 +547,7 @@ namespace ScriptCanvasBuilder auto version = sourceGraph->GetVersion(); if (version.grammarVersion == ScriptCanvas::GrammarVersion::Initial - || version.runtimeVersion == ScriptCanvas::RuntimeVersion::Initial) + || version.runtimeVersion == ScriptCanvas::RuntimeVersion::Initial) { return AZ::Failure(AZStd::string(ScriptCanvas::ParseErrors::SourceUpdateRequired)); } @@ -542,7 +556,7 @@ namespace ScriptCanvasBuilder request.path = input.fullPath; request.name = input.fileNameOnly; request.namespacePath = input.namespacePath; - request.assetId = input.assetID; + request.scriptAssetId = input.assetID; request.graph = sourceGraph; request.rawSaveDebugOutput = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile; request.printModelToConsole = ScriptCanvas::Grammar::g_printAbstractCodeModel; @@ -728,6 +742,6 @@ namespace ScriptCanvasBuilder ScriptCanvas::Translation::Result TranslateToLua(ScriptCanvas::Grammar::Request& request) { request.translationTargetFlags = ScriptCanvas::Translation::TargetFlags::Lua; - return ScriptCanvas::Translation::ParseGraph(request); + return ScriptCanvas::Translation::ParseAndTranslateGraph(request); } } diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp index b767a2b52e..56a170f851 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -19,17 +19,16 @@ #include #include #include - #include #include #include +#include #include #include #include #include #include #include -#include #include namespace ScriptCanvasEditor @@ -83,10 +82,11 @@ namespace ScriptCanvasEditor if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(8, &EditorScriptCanvasComponentVersionConverter) + ->Version(10, &EditorScriptCanvasComponentVersionConverter) ->Field("m_name", &EditorScriptCanvasComponent::m_name) ->Field("m_assetHolder", &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder) - ->Field("m_variableData", &EditorScriptCanvasComponent::m_editableData) + ->Field("runtimeDataIsValid", &EditorScriptCanvasComponent::m_runtimeDataIsValid) + ->Field("runtimeDataOverrides", &EditorScriptCanvasComponent::m_variableOverrides) ; if (AZ::EditContext* editContext = serializeContext->GetEditContext()) @@ -103,9 +103,9 @@ namespace ScriptCanvasEditor ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("Level", 0x9aeacc13)) ->Attribute(AZ::Edit::Attributes::HelpPageURL, "https://o3de.org/docs/user-guide/components/reference/script-canvas/") ->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder, "Script Canvas Asset", "Script Canvas asset associated with this component") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_editableData, "Properties", "Script Canvas Graph Properties") - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->DataElement(AZ::Edit::UIHandlers::Default, &EditorScriptCanvasComponent::m_variableOverrides, "Properties", "Script Canvas Graph Properties") + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) ; } } @@ -133,6 +133,11 @@ namespace ScriptCanvasEditor AzFramework::AssetCatalogEventBus::Handler::BusDisconnect(); } + const AZStd::string& EditorScriptCanvasComponent::GetName() const + { + return m_name; + } + void EditorScriptCanvasComponent::UpdateName() { AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId(); @@ -233,81 +238,67 @@ namespace ScriptCanvasEditor EditorComponentBase::Deactivate(); - //EditorScriptCanvasAssetNotificationBus::Handler::BusDisconnect(); EditorScriptCanvasComponentRequestBus::Handler::BusDisconnect(); EditorContextMenuRequestBus::Handler::BusDisconnect(); } - //========================================================================= + void EditorScriptCanvasComponent::BuildGameEntityData() + { + using namespace ScriptCanvasBuilder; + + m_runtimeDataIsValid = false; + + auto assetTreeOutcome = LoadEditorAssetTree(m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetHint()); + if (!assetTreeOutcome.IsSuccess()) + { + AZ_Warning("ScriptCanvas", false, AZStd::string::format("EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str()).c_str()); + return; + } + + EditorAssetTree& editorAssetTree = assetTreeOutcome.GetValue(); + + auto parseOutcome = ParseEditorAssetTree(editorAssetTree); + if (!parseOutcome.IsSuccess()) + { + AZ_Warning("ScriptCanvas", false, AZStd::string::format("EditorScriptCanvasComponent::BuildGameEntityData failed: %s", parseOutcome.GetError().c_str()).c_str()); + return; + } + + auto& variableOverrides = parseOutcome.GetValue(); + + if (!m_variableOverrides.IsEmpty()) + { + variableOverrides.CopyPreviousOverriddenValues(m_variableOverrides); + } + + m_variableOverrides = parseOutcome.TakeValue(); + m_runtimeDataIsValid = true; + } + void EditorScriptCanvasComponent::BuildGameEntity(AZ::Entity* gameEntity) { - AZ::Data::AssetId editorAssetId = m_scriptCanvasAssetHolder.GetAssetId(); - - if (!editorAssetId.IsValid()) + if (!m_runtimeDataIsValid) { + // this is fine, there could have been no graph set, or set to a graph that failed to compile return; } - AZ::Data::AssetId runtimeAssetId(editorAssetId.m_guid, AZ_CRC("RuntimeData", 0x163310ae)); - AZ::Data::Asset runtimeAsset(runtimeAssetId, azrtti_typeid(), {}); + // build everything again as a sanity check against dependencies. All of the variable overrides that were valid will be copied over + BuildGameEntityData(); - /* - - This defense against creating useless runtime components is pending changes the slice update system. - It also would require better abilities to check asset integrity when building assets that depend - on ScriptCanvas assets. - - AZ::Data::AssetInfo assetInfo; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, runtimeAssetId); - - if (assetInfo.m_assetType == AZ::Data::s_invalidAssetType) + if (!m_runtimeDataIsValid) { - AZ_Warning("ScriptCanvas", false, "No ScriptCanvas Runtime Asset information for Entity ('%s' - '%s') Graph ('%s'), asset may be in error or deleted" - , gameEntity->GetName().c_str() - , GetEntityId().ToString().c_str() - , GetName().c_str()); + AZ_Error("ScriptCanvasBuilder", false, "Runtime information did not build for ScriptCanvas Component using asset: %s", m_scriptCanvasAssetHolder.GetAssetId().ToString().c_str()); return; } - AzFramework::AssetSystem::AssetStatus statusResult = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult(statusResult, &AzFramework::AssetSystem::AssetSystemRequests::GetAssetStatusById, runtimeAssetId); - - if (statusResult != AzFramework::AssetSystem::AssetStatus_Compiled) - { - AZ_Warning("ScriptCanvas", false, "No ScriptCanvas Runtime Asset for Entity ('%s' - '%s') Graph ('%s'), compilation may have failed or not completed" - , gameEntity->GetName().c_str() - , GetEntityId().ToString().c_str() - , GetName().c_str()); - return; - } - */ - - // #functions2 dependency-ctor-args make recursive - auto executionComponent = gameEntity->CreateComponent(runtimeAsset); - ScriptCanvas::VariableData varData; - - for (const auto& varConfig : m_editableData.GetVariables()) - { - if (varConfig.m_graphVariable.GetDatum()->Empty()) - { - AZ_Error("ScriptCanvas", false, "Data loss detected for GraphVariable ('%s') on Entity ('%s' - '%s') Graph ('%s')" - , varConfig.m_graphVariable.GetVariableName().data() - , gameEntity->GetName().c_str() - , GetEntityId().ToString().c_str() - , GetName().c_str()); - } - else - { - varData.AddVariable(varConfig.m_graphVariable.GetVariableName(), varConfig.m_graphVariable); - } - } - - executionComponent->SetVariableOverrides(varData); + auto runtimeComponent = gameEntity->CreateComponent(); + auto runtimeOverrides = ConvertToRuntime(m_variableOverrides); + runtimeComponent->SetRuntimeDataOverrides(runtimeOverrides); } void EditorScriptCanvasComponent::OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) { - // If we removed out asset due to the catalog removing. Just set it back. if (m_removedCatalogId == assetId) { if (!m_scriptCanvasAssetHolder.GetAssetId().IsValid()) @@ -317,12 +308,9 @@ namespace ScriptCanvasEditor } } } - void EditorScriptCanvasComponent::OnCatalogAssetRemoved(const AZ::Data::AssetId& removedAssetId, const AZ::Data::AssetInfo& /*assetInfo*/) { AZ::Data::AssetId assetId = m_scriptCanvasAssetHolder.GetAssetId(); - - // If the Asset gets removed from disk while the Editor is loaded clear out the asset reference. if (assetId == removedAssetId) { m_removedCatalogId = assetId; @@ -355,8 +343,6 @@ namespace ScriptCanvasEditor } } - AzToolsFramework::ScopedUndoBatch undo("Update Entity With New SC Graph"); - AzToolsFramework::ToolsApplicationRequests::Bus::Broadcast(&AzToolsFramework::ToolsApplicationRequests::Bus::Events::AddDirtyEntity, GetEntityId()); AzToolsFramework::ToolsApplicationEvents::Bus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_AttributesAndValues); } @@ -448,7 +434,6 @@ namespace ScriptCanvasEditor { // Invalidate the previously removed catalog id if we are setting a new asset id m_removedCatalogId.SetInvalid(); - SetPrimaryAsset(assetId); } } @@ -469,125 +454,17 @@ namespace ScriptCanvasEditor { if (memoryAsset->GetFileAssetId() == m_scriptCanvasAssetHolder.GetAssetId()) { - LoadVariables(memoryAsset); + auto assetData = memoryAsset->GetAsset(); + AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity(); + AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity"); + BuildGameEntityData(); + AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); UpdateName(); } } - /*! Start Variable Block Implementation */ - void EditorScriptCanvasComponent::AddVariable(AZStd::string_view varName, const ScriptCanvas::GraphVariable& graphVariable) - { - // We only add component properties to the component - if (!graphVariable.IsComponentProperty()) - { - return; - } - - const auto& variableId = graphVariable.GetVariableId(); - ScriptCanvas::EditableVariableConfiguration* originalVarNameValuePair = m_editableData.FindVariable(variableId); - if (!originalVarNameValuePair) - { - m_editableData.AddVariable(varName, graphVariable); - originalVarNameValuePair = m_editableData.FindVariable(variableId); - } - - if (!originalVarNameValuePair) - { - AZ_Error("Script Canvas", false, "Unable to find variable with id %s and name %s on the ScriptCanvas Component. There is an issue in AddVariable", - variableId.ToString().data(), varName.data()); - return; - } - - // Update the variable name as it may have changed - originalVarNameValuePair->m_graphVariable.SetVariableName(varName); - originalVarNameValuePair->m_graphVariable.SetExposureCategory(graphVariable.GetExposureCategory()); - originalVarNameValuePair->m_graphVariable.SetScriptInputControlVisibility(AZ::Edit::PropertyVisibility::Hide); - originalVarNameValuePair->m_graphVariable.SetAllowSignalOnChange(false); - } - - void EditorScriptCanvasComponent::AddNewVariables(const ScriptCanvas::VariableData& graphVarData) - { - for (auto&& variablePair : graphVarData.GetVariables()) - { - AddVariable(variablePair.second.GetVariableName(), variablePair.second); - } - } - - void EditorScriptCanvasComponent::RemoveVariable(const ScriptCanvas::VariableId& varId) - { - m_editableData.RemoveVariable(varId); - } - - void EditorScriptCanvasComponent::RemoveOldVariables(const ScriptCanvas::VariableData& graphVarData) - { - AZStd::vector oldVariableIds; - for (auto varConfig : m_editableData.GetVariables()) - { - const auto& variableId = varConfig.m_graphVariable.GetVariableId(); - - // We only add component sourced graph properties to the script canvas component, so if this variable was switched to a graph-only property remove it. - // Also be sure to remove this variable if it's been deleted entirely. - auto graphVariable = graphVarData.FindVariable(variableId); - if (!graphVariable || !graphVariable->IsComponentProperty()) - { - oldVariableIds.push_back(variableId); - } - } - - for (const auto& oldVariableId : oldVariableIds) - { - RemoveVariable(oldVariableId); - } - } - - bool EditorScriptCanvasComponent::UpdateVariable(const ScriptCanvas::GraphVariable& graphDatum, ScriptCanvas::GraphVariable& updateDatum, ScriptCanvas::GraphVariable& originalDatum) - { - // If the editable datum is the different than the original datum, then the "variable value" has been overridden on this component - - // Variable values only propagate from the Script Canvas graph to this component if the original "variable value" has not been overridden - // by the editable "variable value" on this component and the "variable value" on the graph is different than the variable value on this component - auto isNotOverridden = (*updateDatum.GetDatum()) == (*originalDatum.GetDatum()); - auto scGraphIsModified = (*originalDatum.GetDatum()) != (*graphDatum.GetDatum()); - - if (isNotOverridden && scGraphIsModified) - { - ScriptCanvas::ModifiableDatumView originalDatumView; - originalDatum.ConfigureDatumView(originalDatumView); - - originalDatumView.AssignToDatum((*graphDatum.GetDatum())); - - - ScriptCanvas::ModifiableDatumView updatedDatumView; - updateDatum.ConfigureDatumView(updatedDatumView); - - updatedDatumView.AssignToDatum((*graphDatum.GetDatum())); - - return true; - } - return false; - } - - void EditorScriptCanvasComponent::LoadVariables(const ScriptCanvasMemoryAsset::pointer memoryAsset) - { - auto assetData = memoryAsset->GetAsset(); - - AZ::Entity* scriptCanvasEntity = assetData->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "This graph must have a valid entity"); - - auto variableComponent = scriptCanvasEntity ? AZ::EntityUtils::FindFirstDerivedComponent(scriptCanvasEntity) : nullptr; - if (variableComponent) - { - // Add properties from the SC Asset to the SC Component if they do not exist on the SC Component - AddNewVariables(*variableComponent->GetVariableData()); - RemoveOldVariables(*variableComponent->GetVariableData()); - } - - AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); - } - void EditorScriptCanvasComponent::ClearVariables() { - m_editableData.Clear(); + m_variableOverrides.Clear(); } - /* End Variable Block Implementation*/ } diff --git a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.h b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.h index fbb6829a4f..da4335526f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.h +++ b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -19,8 +19,15 @@ namespace ScriptCanvas namespace ScriptCanvasEditor { - using LoadedInterpretedDependencies = AZStd::vector>; - AZ_INLINE LoadedInterpretedDependencies LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet); + struct LoadedInterpretedDependency + { + AZStd::string path; + AZ::Data::Asset runtimeAsset; + ScriptCanvas::Translation::LuaAssetResult luaAssetResult; + AZStd::vector dependencies; + }; + + AZ_INLINE AZStd::vector LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet); AZ_INLINE LoadTestGraphResult LoadTestGraph(AZStd::string_view path); @@ -49,10 +56,11 @@ namespace ScriptCanvasEditor AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, Reporter& reporter); AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, LoadTestGraphResult& loadGraphResult, Reporter& reporter); AZ_INLINE void RunGraphImplementation(const RunGraphSpec& runGraphSpec, Reporters& reporters); - + AZ_INLINE void Simulate(const DurationSpec& duration); AZ_INLINE void SimulateDuration(const DurationSpec& duration); AZ_INLINE void SimulateSeconds(const DurationSpec& duration); AZ_INLINE void SimulateTicks(const DurationSpec& duration); } // ScriptCanvasEditor + #include diff --git a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl index bb40575367..298c881575 100644 --- a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl +++ b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -26,9 +26,25 @@ namespace ScriptCanvasEditor { using namespace ScriptCanvas; - AZ_INLINE LoadedInterpretedDependencies LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet) + // The runtime context (appropriately) always assumes that EntityIds are overridden, this step copies the values from the runtime data + // over to the override data to simulate build step that does this when building prefabs + AZ_INLINE void CopyAssetEntityIdsToOverrides(RuntimeDataOverrides& runtimeDataOverrides) { - LoadedInterpretedDependencies loadedAssets; + runtimeDataOverrides.m_entityIds.reserve(runtimeDataOverrides.m_runtimeAsset->GetData().m_input.m_entityIds.size()); + for (auto& varEntityPar : runtimeDataOverrides.m_runtimeAsset->GetData().m_input.m_entityIds) + { + runtimeDataOverrides.m_entityIds.push_back(varEntityPar.second); + } + + for (auto& dependency : runtimeDataOverrides.m_dependencies) + { + CopyAssetEntityIdsToOverrides(dependency); + } + } + + AZ_INLINE AZStd::vector LoadInterpretedDepencies(const ScriptCanvas::DependencySet& dependencySet) + { + AZStd::vector loadedAssets; if (!dependencySet.empty()) { @@ -41,7 +57,7 @@ namespace ScriptCanvasEditor AZ_Assert(namespacePath.size() >= 3, "This functions assumes unit test dependencies are in the ScriptCanvas gem unit test folder"); AZStd::string originalPath = namespacePath[2].data(); - + for (size_t index = 3; index < namespacePath.size(); ++index) { originalPath += "/"; @@ -52,11 +68,11 @@ namespace ScriptCanvasEditor { originalPath.resize(originalPath.size() - AZStd::string_view(Grammar::k_internalRuntimeSuffix).size()); } - + AZStd::string path = AZStd::string::format("%s/%s.scriptcanvas", k_unitTestDirPathRelative, originalPath.data()); LoadTestGraphResult loadResult = LoadTestGraph(path); AZ_Assert(loadResult.m_runtimeAsset, "failed to load dependent asset"); - + AZ::Outcome luaAssetOutcome = AZ::Failure(AZStd::string("lua asset creation for function failed")); ScriptCanvasEditor::EditorAssetConversionBus::BroadcastResult(luaAssetOutcome, &ScriptCanvasEditor::EditorAssetConversionBusTraits::CreateLuaAsset, loadResult.m_editorAsset, loadResult.m_graphPath); AZ_Assert(luaAssetOutcome.IsSuccess(), "failed to create Lua asset"); @@ -69,8 +85,9 @@ namespace ScriptCanvasEditor } const ScriptCanvas::Translation::LuaAssetResult& luaAssetResult = luaAssetOutcome.GetValue(); - loadedAssets.push_back({ modulePath, luaAssetResult }); - } + // #functions2_recursive_unit_tests + loadedAssets.push_back({ modulePath, loadResult.m_runtimeAsset, luaAssetResult, {} }); + } } return loadedAssets; @@ -182,7 +199,7 @@ namespace ScriptCanvasEditor RuntimeData runtimeDataBuffer; AZStd::vector dependencyDataBuffer; - LoadedInterpretedDependencies dependencies; + AZStd::vector dependencies; if (runGraphSpec.runSpec.execution == ExecutionMode::Interpreted) { @@ -202,9 +219,12 @@ namespace ScriptCanvasEditor { dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.source.userSubgraphs); + RuntimeDataOverrides runtimeDataOverrides; + runtimeDataOverrides.m_runtimeAsset = loadResult.m_runtimeAsset; + if (!dependencies.empty()) { - // eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework + // #functions2_recursive_unit_tests eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework // in order to test functionality with a dependency stack greater than 2 // load all script assets, and their dependencies, initialize statics on all those dependencies if it is the first time loaded @@ -215,7 +235,7 @@ namespace ScriptCanvasEditor for (auto& dependency : dependencies) { - inMemoryModules.emplace_back(dependency.first, dependency.second.m_scriptAsset); + inMemoryModules.emplace_back(dependency.path, dependency.luaAssetResult.m_scriptAsset); } AZ::ScriptSystemRequestBus::Broadcast(&AZ::ScriptSystemRequests::UseInMemoryRequireHook, inMemoryModules, AZ::ScriptContextIds::DefaultScriptContextId); @@ -224,7 +244,11 @@ namespace ScriptCanvasEditor for (size_t index = 0; index < dependencies.size(); ++index) { auto& dependency = dependencies[index]; - const ScriptCanvas::Translation::LuaAssetResult& depencyAssetResult = dependency.second; + const ScriptCanvas::Translation::LuaAssetResult& depencyAssetResult = dependency.luaAssetResult; + + RuntimeDataOverrides dependencyRuntimeDataOverrides; + dependencyRuntimeDataOverrides.m_runtimeAsset = dependency.runtimeAsset; + runtimeDataOverrides.m_dependencies.push_back(dependencyRuntimeDataOverrides); RuntimeData& dependencyData = dependencyDataBuffer[index]; dependencyData.m_input = depencyAssetResult.m_runtimeInputs; @@ -239,7 +263,9 @@ namespace ScriptCanvasEditor loadResult.m_runtimeAsset.Get()->GetData().m_script = loadResult.m_scriptAsset; loadResult.m_runtimeAsset.Get()->GetData().m_input = luaAssetResult.m_runtimeInputs; loadResult.m_runtimeAsset.Get()->GetData().m_debugMap = luaAssetResult.m_debugMap; - loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent(loadResult.m_runtimeAsset); + loadResult.m_runtimeComponent = loadResult.m_entity->CreateComponent(); + CopyAssetEntityIdsToOverrides(runtimeDataOverrides); + loadResult.m_runtimeComponent->SetRuntimeDataOverrides(runtimeDataOverrides); Execution::Context::InitializeActivationData(loadResult.m_runtimeAsset->GetData()); Execution::InitializeInterpretedStatics(loadResult.m_runtimeAsset->GetData()); } diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h index c3f500c3cc..5746ece85d 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -8,14 +8,14 @@ #pragma once #include +#include #include - +#include #include #include #include +#include #include -#include -#include namespace ScriptCanvasEditor { @@ -27,11 +27,10 @@ namespace ScriptCanvasEditor which it uses to maintain the asset data in memory. Therefore removing an open ScriptCanvasAsset from the file system will remove the reference from the EditorScriptCanvasComponent, but not the reference from the MainWindow allowing the ScriptCanvas graph to still be modified while open - Finally per graph instance variables values are stored on the EditorScriptCanvasComponent and injected into the runtime ScriptCanvas component in BuildGameEntity */ class EditorScriptCanvasComponent - : public AzToolsFramework::Components::EditorComponentBase + : public AzToolsFramework::Components::EditorComponentBase , private EditorContextMenuRequestBus::Handler , private AzFramework::AssetCatalogEventBus::Handler , private EditorScriptCanvasComponentLoggingBus::Handler @@ -54,7 +53,6 @@ namespace ScriptCanvasEditor void Deactivate() override; //===================================================================== - //===================================================================== // EditorComponentBase void BuildGameEntity(AZ::Entity* gameEntity) override; @@ -71,10 +69,10 @@ namespace ScriptCanvasEditor void CloseGraph(); void SetName(const AZStd::string& name) { m_name = name; } - const AZStd::string& GetName() const { return m_name; }; + const AZStd::string& GetName() const; AZ::EntityId GetEditorEntityId() const { return GetEntity() ? GetEntityId() : AZ::EntityId(); } AZ::NamedEntityId GetNamedEditorEntityId() const { return GetEntity() ? GetNamedEntityId() : AZ::NamedEntityId(); } - + //===================================================================== // EditorScriptCanvasComponentRequestBus void SetAssetId(const AZ::Data::AssetId& assetId) override; @@ -119,12 +117,8 @@ namespace ScriptCanvasEditor (void)incompatible; } - //===================================================================== - // AssetCatalogEventBus void OnCatalogAssetAdded(const AZ::Data::AssetId& assetId) override; void OnCatalogAssetRemoved(const AZ::Data::AssetId& assetId, const AZ::Data::AssetInfo& assetInfo) override; - //===================================================================== - void OnScriptCanvasAssetChanged(AZ::Data::AssetId assetId); void UpdateName(); @@ -133,21 +127,15 @@ namespace ScriptCanvasEditor void OnScriptCanvasAssetReady(const ScriptCanvasMemoryAsset::pointer asset); //===================================================================== - void AddVariable(AZStd::string_view varName, const ScriptCanvas::GraphVariable& varDatum); - void AddNewVariables(const ScriptCanvas::VariableData& graphVarData); - void RemoveVariable(const ScriptCanvas::VariableId& varId); - void RemoveOldVariables(const ScriptCanvas::VariableData& graphVarData); - bool UpdateVariable(const ScriptCanvas::GraphVariable& graphDatum, ScriptCanvas::GraphVariable& updateDatum, ScriptCanvas::GraphVariable& originalDatum); - void LoadVariables(const ScriptCanvasMemoryAsset::pointer memoryAsset); + void BuildGameEntityData(); void ClearVariables(); private: AZ::Data::AssetId m_removedCatalogId; AZ::Data::AssetId m_previousAssetId; - AZStd::string m_name; ScriptCanvasAssetHolder m_scriptCanvasAssetHolder; - - ScriptCanvas::EditableVariableData m_editableData; + bool m_runtimeDataIsValid = false; + ScriptCanvasBuilder::BuildVariableOverrides m_variableOverrides; }; } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.cpp index f036835618..634eee5b17 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingDataAggregator.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -289,7 +289,7 @@ namespace ScriptCanvasEditor void LoggingDataAggregator::OnRegistrationDisabled(const AZ::NamedEntityId&, const ScriptCanvas::GraphIdentifier&) { - + } void LoggingDataAggregator::ResetLog() @@ -324,7 +324,7 @@ namespace ScriptCanvasEditor m_hasAnchor = false; m_anchorTimeStamp = ScriptCanvas::Timestamp(0); } - + void LoggingDataAggregator::RegisterScriptCanvas(const AZ::NamedEntityId& entityId, const ScriptCanvas::GraphIdentifier& graphIdentifier) { bool foundMatch = false; @@ -335,7 +335,7 @@ namespace ScriptCanvasEditor if (mapIter->second == graphIdentifier) { foundMatch = true; - AZ_Error("ScriptCanvas", false, "Received a duplicated registration callback."); + AZ_Warning("ScriptCanvas", false, "Received a duplicated registration callback."); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.cpp index a675a62788..b9dd45555b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -15,17 +15,28 @@ namespace ScriptCanvasRuntimeAssetCpp { AddDependencies = 3, ChangeScriptRequirementToAsset, - // add your entry above + + // add description above Current }; + enum class RuntimeDataOverridesVersion : unsigned int + { + Initial = 0, + AddRuntimeAsset, + + // add description above + Current, + }; + enum class FunctionRuntimeDataVersion { MergeBackEnd2dotZero, AddSubgraphInterface, RemoveLegacyData, RemoveConnectionToRuntimeData, - // add your entry above + + // add description above Current }; } @@ -87,9 +98,9 @@ namespace ScriptCanvas { return data.m_input.GetConstructorParameterCount() != 0 || AZStd::any_of(data.m_requiredAssets.begin(), data.m_requiredAssets.end(), [](const AZ::Data::Asset& asset) - { - return RequiresDependencyConstructionParametersRecurse(asset.Get()->m_runtimeData); - }); + { + return RequiresDependencyConstructionParametersRecurse(asset.Get()->m_runtimeData); + }); } bool RuntimeData::RequiresStaticInitialization() const @@ -97,6 +108,80 @@ namespace ScriptCanvas return !m_cloneSources.empty(); } + bool RuntimeDataOverrides::IsPreloadBehaviorEnforced(const RuntimeDataOverrides& overrides) + { + if (overrides.m_runtimeAsset.GetAutoLoadBehavior() != AZ::Data::AssetLoadBehavior::PreLoad) + { + return false; + } + + for (auto& dependency : overrides.m_dependencies) + { + if (!IsPreloadBehaviorEnforced(dependency)) + { + return false; + } + } + + return true; + } + + void RuntimeDataOverrides::EnforcePreloadBehavior() + { + m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); + + for (auto& dependency : m_dependencies) + { + dependency.EnforcePreloadBehavior(); + } + } + + void RuntimeDataOverrides::Reflect(AZ::ReflectContext* context) + { + RuntimeVariable::Reflect(context); + + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Version(static_cast(ScriptCanvasRuntimeAssetCpp::RuntimeDataOverridesVersion::Current)) + ->Field("runtimeAsset", &RuntimeDataOverrides::m_runtimeAsset) + ->Field("variables", &RuntimeDataOverrides::m_variables) + ->Field("variableIndices", &RuntimeDataOverrides::m_variableIndices) + ->Field("entityIds", &RuntimeDataOverrides::m_entityIds) + ->Field("dependencies", &RuntimeDataOverrides::m_dependencies) + ; + } + } + + RuntimeVariable::RuntimeVariable(const AZStd::any& source) + : value(source) + { + } + + RuntimeVariable::RuntimeVariable(AZStd::any&& source) + : value(AZStd::move(source)) + { + } + + void RuntimeVariable::Reflect(AZ::ReflectContext* context) + { + if (auto serializeContext = azrtti_cast(context)) + { + serializeContext->Class() + ->Field("value", &RuntimeVariable::value) + ; + + if (auto editContext = serializeContext->GetEditContext()) + { + editContext->Class("RuntimeVariable", "RuntimeVariable") + ->DataElement(AZ::Edit::UIHandlers::Default, &RuntimeVariable::value, "value", "") + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true) + ; + } + } + } //////////////////////// // SubgraphInterfaceData @@ -118,7 +203,7 @@ namespace ScriptCanvas { *this = AZStd::move(other); } - + SubgraphInterfaceData& SubgraphInterfaceData::operator=(SubgraphInterfaceData&& other) { if (this != &other) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.h index fd746f947d..318fd0790a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Asset/RuntimeAsset.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -21,6 +22,7 @@ namespace ScriptCanvas { class RuntimeAsset; + struct RuntimeVariable; class RuntimeAssetDescription : public AssetDescription { @@ -41,7 +43,7 @@ namespace ScriptCanvas "Script Canvas Runtime", "Script Canvas Runtime", "Icons/ScriptCanvas/Viewport/ScriptCanvas.png", - AZ::Color(1.0f,0.0f,0.0f,1.0f), + AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), false ) {} @@ -82,6 +84,24 @@ namespace ScriptCanvas bool static RequiresDependencyConstructionParametersRecurse(const RuntimeData& data); }; + struct RuntimeDataOverrides + { + AZ_TYPE_INFO(RuntimeDataOverrides, "{CE3C0AE6-4EBA-43B2-B2D5-7AC24A194E63}"); + AZ_CLASS_ALLOCATOR(RuntimeDataOverrides, AZ::SystemAllocator, 0); + + static bool IsPreloadBehaviorEnforced(const RuntimeDataOverrides& overrides); + + static void Reflect(AZ::ReflectContext* reflectContext); + + AZ::Data::Asset m_runtimeAsset; + AZStd::vector m_variables; + AZStd::vector m_variableIndices; + AZStd::vector m_entityIds; + AZStd::vector m_dependencies; + + void EnforcePreloadBehavior(); + }; + class RuntimeAssetBase : public AZ::Data::AssetData { @@ -94,7 +114,6 @@ namespace ScriptCanvas { } - }; template class RuntimeAssetTyped @@ -165,7 +184,7 @@ namespace ScriptCanvas "Script Canvas Function Interface", "Script Canvas Function Interface", "Icons/ScriptCanvas/Viewport/ScriptCanvas_Function.png", - AZ::Color(1.0f,0.0f,0.0f,1.0f), + AZ::Color(1.0f, 0.0f, 0.0f, 1.0f), false ) {} @@ -207,6 +226,6 @@ namespace ScriptCanvas static const char* GetFileExtension() { return "scriptcanvas_fn_compiled"; } static const char* GetFileFilter() { return "*.scriptcanvas_fn_compiled"; } - friend class SubgraphInterfaceAssetHandler; + friend class SubgraphInterfaceAssetHandler; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp index a79c58ea32..a6e02e796f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp @@ -1,12 +1,12 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ - #include +#include #include #include #include @@ -17,6 +17,33 @@ namespace ScriptCanvas { + ScopedAuxiliaryEntityHandler::ScopedAuxiliaryEntityHandler(AZ::Entity* buildEntity) + : m_buildEntity(buildEntity) + , m_wasAdded(false) + { + if (AZ::Interface::Get() != nullptr) + { + AZ::Interface::Get()->RemoveEntity(buildEntity); + } + + if (buildEntity->GetState() == AZ::Entity::State::Constructed) + { + buildEntity->Init(); + m_wasAdded = true; + } + } + + ScopedAuxiliaryEntityHandler::~ScopedAuxiliaryEntityHandler() + { + if (!m_wasAdded) + { + if (AZ::Interface::Get() != nullptr) + { + AZ::Interface::Get()->AddEntity(m_buildEntity); + } + } + } + bool IsNamespacePathEqual(const NamespacePath& lhs, const NamespacePath& rhs) { if (lhs.size() != rhs.size()) @@ -128,4 +155,3 @@ namespace ScriptCanvas runtimeVersion = RuntimeVersion::Current; } } - diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index 78e51ddbb0..4f76e84775 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,7 @@ namespace AZ { class Entity; class ReflectContext; - + template bool ReadAttribute(t_Attribute& resultOut, AttributeId id, const t_Container& attributes) { @@ -41,7 +42,7 @@ namespace ScriptCanvas // The actual value in each location initialized to GraphOwnerId is populated with the owning entity at editor-time, Asset Processor-time, or runtime, as soon as the owning entity is known. using GraphOwnerIdType = AZ::EntityId; static const GraphOwnerIdType GraphOwnerId = AZ::EntityId(0xacedc0de); - + // A place holder identifier for unique runtime graph on Entity that is running more than one instance of the same graph. // This allows multiple instances of the same graph to be addressed individually on the same entity. // The actual value in each location initialized to UniqueId is populated at run-time. @@ -52,7 +53,7 @@ namespace ScriptCanvas constexpr const char* k_OnVariableWriteEventName = "OnVariableValueChanged"; constexpr const char* k_OnVariableWriteEbusName = "VariableNotification"; - + class Node; class Edge; @@ -195,7 +196,7 @@ namespace ScriptCanvas using PropertyFields = AZStd::vector>; - using NamedActiveEntityId = AZ::NamedEntityId; + using NamedActiveEntityId = AZ::NamedEntityId; using NamedNodeId = NamedId; using NamedSlotId = NamedId; @@ -204,7 +205,26 @@ namespace ScriptCanvas using EBusBusId = AZ::Crc32; using ScriptCanvasId = AZ::EntityId; enum class AzEventIdentifier : size_t {}; - + + struct RuntimeVariable + { + AZ_TYPE_INFO(RuntimeVariable, "{6E969359-5AF5-4ECA-BE89-A96AB30A624E}"); + AZ_CLASS_ALLOCATOR(RuntimeVariable, AZ::SystemAllocator, 0); + + static void Reflect(AZ::ReflectContext* reflectContext); + + AZStd::any value; + + RuntimeVariable() = default; + RuntimeVariable(const RuntimeVariable&) = default; + RuntimeVariable(RuntimeVariable&&) = default; + explicit RuntimeVariable(const AZStd::any& source); + explicit RuntimeVariable(AZStd::any&& source); + + RuntimeVariable& operator=(const RuntimeVariable&) = default; + RuntimeVariable& operator=(RuntimeVariable&&) = default; + }; + struct NamespacePathHasher { AZ_FORCE_INLINE size_t operator()(const NamespacePath& path) const @@ -245,6 +265,17 @@ namespace ScriptCanvas }; using ScriptCanvasSettingsRequestBus = AZ::EBus; + + class ScopedAuxiliaryEntityHandler + { + public: + ScopedAuxiliaryEntityHandler(AZ::Entity* buildEntity); + ~ScopedAuxiliaryEntityHandler(); + + private: + bool m_wasAdded = false; + AZ::Entity* m_buildEntity = nullptr; + }; } namespace AZStd diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index d51fc0038e..3c70031af0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -17,15 +17,55 @@ #include #include - #include #include "DatumBus.h" namespace DatumHelpers { + enum Version + { + JSONSerializerSupport = 6, + + // label your entry above + Current + }; + using namespace ScriptCanvas; - + + bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& rootDataElementNode) + { + if (rootDataElementNode.GetVersion() <= Version::JSONSerializerSupport) + { + auto storageElementIndex = rootDataElementNode.FindElement(AZ_CRC_CE("m_datumStorage")); + if (storageElementIndex == -1) + { + AZ_Error("ScriptCanvas", false, "Datum Version conversion failed: 'm_datumStorage' was missing."); + return false; + } + + auto& storageElement = rootDataElementNode.GetSubElement(storageElementIndex); + + AZStd::any previousStorage; + if (!storageElement.GetData(previousStorage)) + { + AZ_Error("ScriptCanvas", false, "Datum Version conversion failed: Could not retrieve old version of 'm_datumStorage'."); + return false; + } + + rootDataElementNode.RemoveElement(storageElementIndex); + + RuntimeVariable newStorage(previousStorage); + if (!rootDataElementNode.AddElementWithData(context, "m_datumStorage", newStorage)) + { + AZ_Error("ScriptCanvas", false, "Datum Version conversion failed: Could not add new version of 'm_datumStorage'."); + return false; + } + } + + return true; + } + template struct ImplicitConversionHelp { @@ -129,7 +169,7 @@ namespace DatumHelpers return true; } - + AZ_FORCE_INLINE bool ConvertImplicitlyCheckedVector3(const void* source, const Data::Type& targetType, AZStd::any& target, const AZ::BehaviorClass* targetClass) { const AZ::Vector3& sourceVector = *reinterpret_cast(source); @@ -246,10 +286,10 @@ namespace DatumHelpers ? Data::IsVectorType(type.GetAZType()) : Data::IsVectorType(type); } - + AZ_FORCE_INLINE Data::eType GetVectorType(const Data::Type& type) { - return type.GetType() == Data::eType::BehaviorContextObject + return type.GetType() == Data::eType::BehaviorContextObject ? Data::FromAZType(type.GetAZType()).GetType() : type.GetType(); } @@ -257,7 +297,7 @@ namespace DatumHelpers AZ_FORCE_INLINE bool ConvertImplicitlyCheckedVector(const Data::Type& sourceType, const void* source, const Data::Type& targetType, AZStd::any& target, const AZ::BehaviorClass* targetClass) { const Data::eType sourceVectorType = GetVectorType(sourceType); - + switch (sourceVectorType) { case Data::eType::Vector2: @@ -277,9 +317,9 @@ namespace DatumHelpers AZ_Assert ( (a.GetType() == Data::eType::BehaviorContextObject && Data::IsAutoBoxedType(b)) - || + || (b.GetType() == Data::eType::BehaviorContextObject && Data::IsAutoBoxedType(a)) - , "these types are not convertible, or need no conversion."); + , "these types are not convertible, or need no conversion."); return a.GetType() == Data::eType::BehaviorContextObject ? b.GetType() : a.GetType(); } @@ -287,15 +327,15 @@ namespace DatumHelpers AZ_FORCE_INLINE bool ConvertImplicitlyChecked(const Data::Type& sourceType, const void* source, const Data::Type& targetType, AZStd::any& target, const AZ::BehaviorClass* targetClass) { AZ_Assert(!targetType.IS_A(sourceType), "Bad use of conversion, target type IS-A source type"); - + if (IsAnyVectorType(sourceType) && IsAnyVectorType(targetType)) { return ConvertImplicitlyCheckedVector(sourceType, source, targetType, target, targetClass); - } + } else if (Data::IsConvertible(sourceType, targetType)) { auto conversionType = GetMathConversionType(targetType, sourceType); - + switch (conversionType) { case Data::eType::AABB: @@ -323,7 +363,7 @@ namespace DatumHelpers return false; } - + template AZ_INLINE bool FromBehaviorContext(const AZ::Uuid& typeID, const void* source, AZStd::any& destination) { @@ -339,7 +379,7 @@ namespace DatumHelpers return false; } - + AZ_INLINE bool FromBehaviorContextAABB(const AZ::Uuid& typeID, const void* source, AZStd::any& destination) { return FromBehaviorContext(typeID, source, destination); @@ -364,7 +404,7 @@ namespace DatumHelpers { return FromBehaviorContext(typeID, source, destination); } - + AZ_INLINE bool FromBehaviorContextEntityID(const AZ::Uuid& typeID, const void* source, AZStd::any& destination) { return FromBehaviorContext(typeID, source, destination); @@ -443,7 +483,7 @@ namespace DatumHelpers { return FromBehaviorContext(typeID, source, destination); } - + AZ_INLINE bool FromBehaviorContextVector2(const AZ::Uuid& typeID, const void* source, AZStd::any& destination) { AZ::Vector2* target = AZStd::any_cast(&destination); @@ -532,7 +572,7 @@ namespace DatumHelpers { return FromBehaviorContext(typeID, source, destination); } - + template AZ_INLINE bool IsDataEqual(const void* lhs, const void* rhs) { @@ -952,7 +992,7 @@ namespace DatumHelpers { return ToBehaviorContext(valueOut, typeIDOut, valueIn); } - + AZ_INLINE bool ToBehaviorContextString(AZ::BehaviorValueParameter& destination, const void* valueIn) { if (Data::IsString(destination.m_typeId)) @@ -1006,7 +1046,7 @@ namespace DatumHelpers vector4out->SetY(vector2in->GetY()); return true; } - + return false; } @@ -1029,7 +1069,7 @@ namespace DatumHelpers *reinterpret_cast(valueOut) = AZ::Vector4::CreateFromVector3(*vector3in); return true; } - + return false; } @@ -1052,7 +1092,7 @@ namespace DatumHelpers *reinterpret_cast(valueOut) = *vector4in; return true; } - + return false; } @@ -1060,7 +1100,7 @@ namespace DatumHelpers { const AZ::Uuid& typeIDOut = destination.m_typeId; void* valueOut = destination.GetValueAddress(); - + if (valueIn) { switch (typeIn.GetType()) @@ -1128,7 +1168,7 @@ namespace DatumHelpers AZ::BehaviorValueParameter parameter; parameter.m_typeId = description.m_typeId; parameter.m_name = name.data(); - + if (description.m_traits & AZ::BehaviorParameter::TR_POINTER) { pointer = value; @@ -1153,7 +1193,7 @@ namespace DatumHelpers if (parameterDesc.m_typeId == azrtti_typeid() && (parameterDesc.m_traits & (AZ::BehaviorParameter::TR_POINTER | AZ::BehaviorParameter::TR_CONST))) { - AZStd::string_view parameterString = *reinterpret_cast(source); + AZStd::string_view parameterString = *reinterpret_cast(source); return AZ::Success(AZStd::string(parameterString)); } else if (parameterDesc.m_typeId == azrtti_typeid()) @@ -1161,7 +1201,7 @@ namespace DatumHelpers const AZStd::string_view* parameterString = nullptr; if (parameterDesc.m_traits & AZ::BehaviorParameter::TR_POINTER) { - parameterString = *reinterpret_cast(source); + parameterString = *reinterpret_cast(source); } else { @@ -1209,7 +1249,7 @@ namespace ScriptCanvas { Initialize(type, originality, source, sourceTypeID); } - + Datum::Datum(const AZStd::string& behaviorClassName, eOriginality originality) : Datum(Data::FromAZType(AZ::BehaviorContextHelper::GetClassType(behaviorClassName)), originality, nullptr, AZ::Uuid::CreateNull()) { @@ -1227,12 +1267,12 @@ namespace ScriptCanvas Datum::Datum(const AZ::BehaviorValueParameter& value) : Datum(value, - !(value.m_traits & (AZ::BehaviorParameter::TR_POINTER | AZ::BehaviorParameter::TR_REFERENCE)) ? eOriginality::Original : eOriginality::Copy, + !(value.m_traits& (AZ::BehaviorParameter::TR_POINTER | AZ::BehaviorParameter::TR_REFERENCE)) ? eOriginality::Original : eOriginality::Copy, value.m_value) { } - void Datum::ReconfigureDatumTo(Datum&& datum) + void Datum::ReconfigureDatumTo(Datum&& datum) { bool isOverloadedStorage = datum.m_isOverloadedStorage; @@ -1258,7 +1298,7 @@ namespace ScriptCanvas InitializeOverloadedStorage(source.m_type, m_originality); m_class = source.m_class; m_type = source.m_type; - + if (!Data::IsValueType(m_type)) { AZ::BehaviorContext* behaviorContext = nullptr; @@ -1268,15 +1308,15 @@ namespace ScriptCanvas if (classIter != behaviorContext->m_typeToClassMap.end()) { - BehaviorContextObjectPtr sourceObjectPtr = (*AZStd::any_cast(&source.m_storage)); + BehaviorContextObjectPtr sourceObjectPtr = (*AZStd::any_cast(&source.m_storage.value)); BehaviorContextObjectPtr newObjectPtr = sourceObjectPtr->CloneObject((*classIter->second)); - m_storage = AZStd::move(newObjectPtr); - BehaviorContextObjectPtr newSourceObjectPtr = (*AZStd::any_cast(&m_storage)); + m_storage.value = AZStd::move(newObjectPtr); + BehaviorContextObjectPtr newSourceObjectPtr = (*AZStd::any_cast(&m_storage.value)); } } else { - m_storage = source.m_storage; + m_storage.value = source.m_storage.value; m_conversionStorage = source.m_conversionStorage; } @@ -1303,7 +1343,7 @@ namespace ScriptCanvas { AZ::AttributeReader operatorAttrReader(nullptr, operatorAttr); AZ::Script::Attributes::OperatorType methodAttribute{}; - + if (operatorAttrReader.Read(methodAttribute) && methodAttribute == operatorType && method->HasResult() @@ -1314,16 +1354,16 @@ namespace ScriptCanvas AZ::BehaviorValueParameter result(&comparisonResult); AZStd::array params; AZ::Outcome lhsArgument = lhs.ToBehaviorValueParameter(*method->GetArgument(0)); - + if (lhsArgument.IsSuccess() && lhsArgument.GetValue().m_value) { params[0].Set(lhsArgument.GetValue()); AZ::Outcome rhsArgument = rhs.ToBehaviorValueParameter(*method->GetArgument(1)); - + if (rhsArgument.IsSuccess() && rhsArgument.GetValue().m_value) { params[1].Set(rhsArgument.GetValue()); - + if (method->Call(params.data(), aznumeric_caster(params.size()), &result)) { return AZ::Success(comparisonResult); @@ -1339,7 +1379,7 @@ namespace ScriptCanvas void Datum::Clear() { - m_storage.clear(); + m_storage.value.clear(); m_class = nullptr; m_type = Data::Type::Invalid(); } @@ -1352,12 +1392,12 @@ namespace ScriptCanvas { if (m_pointer) { - DatumHelpers::FromBehaviorContextNumber(resultType.m_typeId, m_pointer, m_storage); + DatumHelpers::FromBehaviorContextNumber(resultType.m_typeId, m_pointer, m_storage.value); } } else { - DatumHelpers::FromBehaviorContextNumber(resultType.m_typeId, reinterpret_cast(&m_conversionStorage), m_storage); + DatumHelpers::FromBehaviorContextNumber(resultType.m_typeId, reinterpret_cast(&m_conversionStorage), m_storage.value); } } else if (IS_A(Data::Type::String()) && !Data::IsString(resultType.m_typeId) && AZ::BehaviorContextHelper::IsStringParameter(resultType)) @@ -1365,7 +1405,7 @@ namespace ScriptCanvas void* storageAddress = (resultType.m_traits & AZ::BehaviorParameter::TR_POINTER) ? reinterpret_cast(&m_pointer) : AZStd::any_cast(&m_conversionStorage); if (auto stringOutcome = DatumHelpers::ConvertBehaviorContextString(resultType, storageAddress)) { - m_storage = stringOutcome.GetValue(); + m_storage.value = stringOutcome.GetValue(); } } else if (m_type.GetType() == Data::eType::BehaviorContextObject @@ -1373,73 +1413,73 @@ namespace ScriptCanvas { if (m_pointer) { - m_storage = BehaviorContextObject::CreateReference(resultType.m_typeId, m_pointer); + m_storage.value = BehaviorContextObject::CreateReference(resultType.m_typeId, m_pointer); } } } - + bool Datum::FromBehaviorContext(const void* source, const AZ::Uuid& typeID) { const auto& type = Data::FromAZType(typeID); InitializeOverloadedStorage(type, eOriginality::Copy); - + if (IS_A(type)) { switch (m_type.GetType()) { case ScriptCanvas::Data::eType::AABB: - return DatumHelpers::FromBehaviorContextAABB(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextAABB(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::BehaviorContextObject: return FromBehaviorContextObject(m_class, source); - + case ScriptCanvas::Data::eType::Boolean: - return DatumHelpers::FromBehaviorContextBool(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextBool(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Color: - return DatumHelpers::FromBehaviorContextColor(typeID, source, m_storage); - + return DatumHelpers::FromBehaviorContextColor(typeID, source, m_storage.value); + case ScriptCanvas::Data::eType::CRC: - return DatumHelpers::FromBehaviorContextCRC(typeID, source, m_storage); - + return DatumHelpers::FromBehaviorContextCRC(typeID, source, m_storage.value); + case ScriptCanvas::Data::eType::EntityID: - return DatumHelpers::FromBehaviorContextEntityID(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextEntityID(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Matrix3x3: - return DatumHelpers::FromBehaviorContextMatrix3x3(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextMatrix3x3(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Matrix4x4: - return DatumHelpers::FromBehaviorContextMatrix4x4(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextMatrix4x4(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Number: - return DatumHelpers::FromBehaviorContextNumber(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextNumber(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::OBB: - return DatumHelpers::FromBehaviorContextOBB(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextOBB(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Plane: - return DatumHelpers::FromBehaviorContextPlane(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextPlane(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Quaternion: - return DatumHelpers::FromBehaviorContextQuaternion(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextQuaternion(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::String: - return DatumHelpers::FromBehaviorContextString(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextString(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Transform: - return DatumHelpers::FromBehaviorContextTransform(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextTransform(typeID, source, m_storage.value); case ScriptCanvas::Data::eType::Vector2: - return DatumHelpers::FromBehaviorContextVector2(typeID, source, m_storage); - + return DatumHelpers::FromBehaviorContextVector2(typeID, source, m_storage.value); + case ScriptCanvas::Data::eType::Vector3: - return DatumHelpers::FromBehaviorContextVector3(typeID, source, m_storage); - + return DatumHelpers::FromBehaviorContextVector3(typeID, source, m_storage.value); + case ScriptCanvas::Data::eType::Vector4: - return DatumHelpers::FromBehaviorContextVector4(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextVector4(typeID, source, m_storage.value); } } - else if (DatumHelpers::ConvertImplicitlyChecked(type, source, m_type, m_storage, m_class)) + else if (DatumHelpers::ConvertImplicitlyChecked(type, source, m_type, m_storage.value, m_class)) { return true; } @@ -1455,14 +1495,14 @@ namespace ScriptCanvas bool Datum::FromBehaviorContextNumber(const void* source, const AZ::Uuid& typeID) { - return DatumHelpers::FromBehaviorContextNumber(typeID, source, m_storage); + return DatumHelpers::FromBehaviorContextNumber(typeID, source, m_storage.value); } bool Datum::FromBehaviorContextObject(const AZ::BehaviorClass* behaviorClass, const void* source) { if (behaviorClass) { - m_storage = BehaviorContextObject::CreateReference(behaviorClass->m_typeId, const_cast(source)); + m_storage.value = BehaviorContextObject::CreateReference(behaviorClass->m_typeId, const_cast(source)); return true; } @@ -1471,10 +1511,10 @@ namespace ScriptCanvas const void* Datum::GetValueAddress() const { - return !m_storage.empty() - ? m_type.GetType() != Data::eType::BehaviorContextObject - ? AZStd::any_cast(&m_storage) - : (*AZStd::any_cast(&m_storage))->Get() + return !m_storage.value.empty() + ? m_type.GetType() != Data::eType::BehaviorContextObject + ? AZStd::any_cast(&m_storage.value) + : (*AZStd::any_cast(&m_storage.value))->Get() : nullptr; } @@ -1488,7 +1528,7 @@ namespace ScriptCanvas AZ_Error("ScriptCanvas", Empty(), "double initialized datum"); m_type = type; - + switch (type.GetType()) { case ScriptCanvas::Data::eType::AABB: @@ -1532,10 +1572,10 @@ namespace ScriptCanvas case ScriptCanvas::Data::eType::Quaternion: return InitializeQuaternion(source); - + case ScriptCanvas::Data::eType::String: return InitializeString(source, sourceTypeID); - + case ScriptCanvas::Data::eType::Transform: return InitializeTransform(source); @@ -1554,13 +1594,13 @@ namespace ScriptCanvas bool Datum::InitializeAABB(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeAssetId(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } @@ -1594,7 +1634,7 @@ namespace ScriptCanvas } const auto& type = Data::FromAZType(description.m_typeId); - const eOriginality originality + const eOriginality originality = !(description.m_traits & (AZ::BehaviorParameter::TR_POINTER | AZ::BehaviorParameter::TR_REFERENCE)) ? eOriginality::Original : eOriginality::Copy; @@ -1621,11 +1661,11 @@ namespace ScriptCanvas if (m_originality == eOriginality::Original) { - m_storage = BehaviorContextObject::Create(behaviorClass, source); + m_storage.value = BehaviorContextObject::Create(behaviorClass, source); } else { - m_storage = BehaviorContextObject::CreateReference(behaviorClass.m_typeId, const_cast(source)); + m_storage.value = BehaviorContextObject::CreateReference(behaviorClass.m_typeId, const_cast(source)); } return true; @@ -1636,68 +1676,68 @@ namespace ScriptCanvas bool Datum::InitializeBool(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeColor(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeCRC(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeEntityID(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeNamedEntityID(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeMatrix3x3(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeMatrix4x4(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeNumber(const void* source, const AZ::Uuid& sourceTypeID) { - m_storage = Data::Traits::GetDefault(); - return (source && DatumHelpers::FromBehaviorContextNumber(sourceTypeID, source, m_storage)) || true; + m_storage.value = Data::Traits::GetDefault(); + return (source && DatumHelpers::FromBehaviorContextNumber(sourceTypeID, source, m_storage.value)) || true; } bool Datum::InitializeOBB(const void* source) { - m_storage = source - ? *reinterpret_cast(source) + m_storage.value = source + ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializePlane(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeQuaternion(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } @@ -1707,49 +1747,49 @@ namespace ScriptCanvas { if (sourceTypeID == azrtti_typeid()) { - m_storage = Data::StringType(*reinterpret_cast(source)); + m_storage.value = Data::StringType(*reinterpret_cast(source)); } else if (sourceTypeID == azrtti_typeid()) { - m_storage = Data::StringType(reinterpret_cast(source)); + m_storage.value = Data::StringType(reinterpret_cast(source)); } else { - m_storage = *reinterpret_cast(source); + m_storage.value = *reinterpret_cast(source); } } else { - m_storage = Data::Traits::GetDefault(); + m_storage.value = Data::Traits::GetDefault(); } return true; } bool Datum::InitializeTransform(const void* source) { - m_storage = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); + m_storage.value = source ? *reinterpret_cast(source) : Data::Traits::GetDefault(); return true; } bool Datum::InitializeVector2(const void* source, const AZ::Uuid& sourceTypeID) { - m_storage = Data::Traits::GetDefault(); + m_storage.value = Data::Traits::GetDefault(); // return a success regardless, but do the initialization first if source is not null - return (source && DatumHelpers::FromBehaviorContextVector2(sourceTypeID, source, m_storage)) || true; + return (source && DatumHelpers::FromBehaviorContextVector2(sourceTypeID, source, m_storage.value)) || true; } bool Datum::InitializeVector3(const void* source, const AZ::Uuid& sourceTypeID) { - m_storage = Data::Traits::GetDefault(); + m_storage.value = Data::Traits::GetDefault(); // return a success regardless, but do the initialization first if source is not null - return (source && DatumHelpers::FromBehaviorContextVector3(sourceTypeID, source, m_storage)) || true; + return (source && DatumHelpers::FromBehaviorContextVector3(sourceTypeID, source, m_storage.value)) || true; } bool Datum::InitializeVector4(const void* source, const AZ::Uuid& sourceTypeID) { - m_storage = Data::Traits::GetDefault(); + m_storage.value = Data::Traits::GetDefault(); // return a success regardless, but do the initialization first if source is not null - return (source && DatumHelpers::FromBehaviorContextVector4(sourceTypeID, source, m_storage)) || true; + return (source && DatumHelpers::FromBehaviorContextVector4(sourceTypeID, source, m_storage.value)) || true; } void Datum::SetType(const Data::Type& dataType) @@ -1759,7 +1799,7 @@ namespace ScriptCanvas if (dataType.IsValid()) { m_isDefaultConstructed = false; - + Datum tempDatum(dataType, ScriptCanvas::Datum::eOriginality::Original); ReconfigureDatumTo(AZStd::move(tempDatum)); } @@ -1787,18 +1827,18 @@ namespace ScriptCanvas auto dataTraitIt = typeIdTraitMap.find(m_type.GetType()); if (dataTraitIt != typeIdTraitMap.end()) { - return dataTraitIt->second.m_dataTraits.IsDefault(m_storage, m_type); + return dataTraitIt->second.m_dataTraits.IsDefault(m_storage.value, m_type); } AZ_Error("Script Canvas", m_isOverloadedStorage, "Unsupported ScriptCanvas Data type"); return true; } - + void* Datum::ModResultAddress() { return m_type.GetType() != Data::eType::BehaviorContextObject - ? AZStd::any_cast(&m_storage) - : (*AZStd::any_cast(&m_storage))->Mod(); + ? AZStd::any_cast(&m_storage.value) + : (*AZStd::any_cast(&m_storage.value))->Mod(); } void* Datum::ModValueAddress() const @@ -1821,12 +1861,12 @@ namespace ScriptCanvas InitializeOverloadedStorage(source.m_type, m_originality); m_class = AZStd::move(source.m_class); m_type = AZStd::move(source.m_type); - if (!source.m_storage.empty()) + if (!source.m_storage.value.empty()) { - m_storage = AZStd::move(source.m_storage); + m_storage.value = AZStd::move(source.m_storage.value); } } - else if (!DatumHelpers::ConvertImplicitlyChecked(source.GetType(), source.GetValueAddress(), m_type, m_storage, m_class)) + else if (!DatumHelpers::ConvertImplicitlyChecked(source.GetType(), source.GetValueAddress(), m_type, m_storage.value, m_class)) { AZ_Error("Script Canvas", false, "Failed to convert from %s to %s", GetName(source.GetType()).c_str(), GetName(m_type).c_str()); } @@ -1852,9 +1892,9 @@ namespace ScriptCanvas InitializeOverloadedStorage(source.m_type, m_originality); m_class = source.m_class; m_type = source.m_type; - m_storage = source.m_storage; + m_storage.value = source.m_storage.value; } - else if (!DatumHelpers::ConvertImplicitlyChecked(source.GetType(), source.GetValueAddress(), m_type, m_storage, m_class)) + else if (!DatumHelpers::ConvertImplicitlyChecked(source.GetType(), source.GetValueAddress(), m_type, m_storage.value, m_class)) { AZ_Error("Script Canvas", false, "Failed to convert from %s to %s", GetName(source.GetType()).c_str(), GetName(m_type).c_str()); } @@ -1924,7 +1964,7 @@ namespace ScriptCanvas { return CallComparisonOperator(AZ::Script::Attributes::OperatorType::LessThan, m_class, *this, other); } - else + else { return AZ::Success(DatumHelpers::IsDataLess(m_type, GetValueAddress(), other.GetValueAddress())); } @@ -1970,7 +2010,7 @@ namespace ScriptCanvas } ComparisonOutcome isLessEqualResult = (*this <= other); - + if (isLessEqualResult.IsSuccess()) { return AZ::Success(!isLessEqualResult.GetValue()); @@ -1989,7 +2029,7 @@ namespace ScriptCanvas } ComparisonOutcome isLessResult = (*this < other); - + if (isLessResult.IsSuccess()) { return AZ::Success(!isLessResult.GetValue()); @@ -2028,7 +2068,7 @@ namespace ScriptCanvas if (auto serializeContext = azrtti_cast(reflection)) { serializeContext->Class() - ->Version(6) + ->Version(DatumHelpers::Version::Current, &DatumHelpers::VersionConverter) ->EventHandler() ->Field("m_isUntypedStorage", &Datum::m_isOverloadedStorage) ->Field("m_type", &Datum::m_type) @@ -2041,13 +2081,13 @@ namespace ScriptCanvas { editContext->Class("Datum", "Datum") ->ClassElement(AZ::Edit::ClassElements::EditorData, "Datum") - ->Attribute(AZ::Edit::Attributes::Visibility, &Datum::GetVisibility) - ->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &Datum::GetLabel) + ->Attribute(AZ::Edit::Attributes::Visibility, &Datum::GetVisibility) + ->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &Datum::GetLabel) ->DataElement(AZ::Edit::UIHandlers::Default, &Datum::m_storage, "Datum", "") - ->Attribute(AZ::Edit::Attributes::Visibility, &Datum::GetDatumVisibility) - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true) - ->Attribute(AZ::Edit::Attributes::ChangeNotify, &Datum::OnDatumEdited) + ->Attribute(AZ::Edit::Attributes::Visibility, &Datum::GetDatumVisibility) + ->Attribute(AZ::Edit::Attributes::AutoExpand, true) + ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, true) + ->Attribute(AZ::Edit::Attributes::ChangeNotify, &Datum::OnDatumEdited) ; } } @@ -2066,7 +2106,7 @@ namespace ScriptCanvas return findIt != uniqueIdMap.end() ? findIt->second : sourceId; }, serializeContext, false); } - + void Datum::SetToDefaultValueOfType() { if (m_isOverloadedStorage) @@ -2079,7 +2119,7 @@ namespace ScriptCanvas auto dataTraitIt = typeIdTraitMap.find(m_type.GetType()); if (dataTraitIt != typeIdTraitMap.end()) { - m_storage = dataTraitIt->second.m_dataTraits.GetDefault(m_type); + m_storage.value = dataTraitIt->second.m_dataTraits.GetDefault(m_type); } else { @@ -2119,7 +2159,7 @@ namespace ScriptCanvas return AZ::Edit::PropertyVisibility::ShowChildrenOnly; } } - + void Datum::SetNotificationsTarget(AZ::EntityId notificationId) { m_notificationId = notificationId; @@ -2129,12 +2169,12 @@ namespace ScriptCanvas { if (m_type.GetType() == Data::eType::BehaviorContextObject) { - BehaviorContextObjectPtr ptr = (*AZStd::any_cast(&m_storage)); + BehaviorContextObjectPtr ptr = (*AZStd::any_cast(&m_storage.value)); return ptr->ToAny(); } else { - return m_storage; + return m_storage.value; } } @@ -2144,11 +2184,11 @@ namespace ScriptCanvas AZ::BehaviorContext* behaviorContext = nullptr; AZ::ComponentApplicationBus::BroadcastResult(behaviorContext, &AZ::ComponentApplicationRequests::GetBehaviorContext); AZ_Assert(behaviorContext, "Script Canvas can't do anything without a behavior context!"); - AZ::BehaviorClass* destinationBehaviorClass = AZ::BehaviorContextHelper::GetClass(behaviorContext, destination.m_typeId); + AZ::BehaviorClass* destinationBehaviorClass = AZ::BehaviorContextHelper::GetClass(behaviorContext, destination.m_typeId); const auto targetType = Data::FromAZType(destination.m_typeId); - - const bool success = - ( (IS_A(targetType) || IsConvertibleTo(targetType)) || (IS_A(Data::Type::String()) && AZ::BehaviorContextHelper::IsStringParameter(destination)) ) + + const bool success = + ((IS_A(targetType) || IsConvertibleTo(targetType)) || (IS_A(Data::Type::String()) && AZ::BehaviorContextHelper::IsStringParameter(destination))) && DatumHelpers::ToBehaviorContext(m_type, GetValueAddress(), destination, destinationBehaviorClass); AZ_Error("Script Canvas", success, "Cannot push Datum with type %s into BehaviorValueParameter expecting type %s", GetName(m_type).c_str(), GetName(targetType).c_str()); @@ -2176,9 +2216,9 @@ namespace ScriptCanvas AZ::Outcome Datum::ToBehaviorValueParameter(const AZ::BehaviorParameter& description) const { AZ_Assert(m_isOverloadedStorage || IS_A(Data::FromAZType(description.m_typeId)) || IsConvertibleTo(description), "Mismatched type going to behavior value parameter: %s", description.m_name); - + const_cast(this)->InitializeOverloadedStorage(Data::FromAZType(description.m_typeId), eOriginality::Copy); - + if (!Data::IsValueType(m_type) && !SatisfiesTraits(description.m_traits)) { return AZ::Failure(AZStd::string("Attempting to convert null value to BehaviorValueParameter that expects reference or value")); @@ -2218,7 +2258,7 @@ namespace ScriptCanvas return AZ::Success(parameter); } } - + AZ::Outcome Datum::ToBehaviorValueParameterResult([[maybe_unused]] const AZ::BehaviorParameter& description, [[maybe_unused]] const AZStd::string_view className, [[maybe_unused]] const AZStd::string_view methodName) { AZ_Assert(m_isOverloadedStorage || IS_A(Data::FromAZType(description.m_typeId)) || IsConvertibleTo(description), "Mismatched type going to behavior value parameter: %s (Context: %s :: %s)", description.m_name, className.data(), methodName.data()); @@ -2245,7 +2285,7 @@ namespace ScriptCanvas if (description.m_traits & AZ::BehaviorParameter::TR_POINTER) { m_pointer = ModResultAddress(); - + if (!m_pointer) { return AZ::Failure(AZStd::string("nowhere to go for the for behavior context result")); @@ -2257,12 +2297,12 @@ namespace ScriptCanvas else { parameter.m_value = ModResultAddress(); - + if (!parameter.m_value) { return AZ::Failure(AZStd::string("nowhere to go for the for behavior context result")); } - + parameter.m_traits = 0; } } @@ -2271,7 +2311,7 @@ namespace ScriptCanvas parameter.m_typeId = description.m_typeId; /// \todo verify there is no polymorphic danger here parameter.m_name = m_class ? m_class->m_name.c_str() : Data::GetBehaviorContextName(m_type); parameter.m_azRtti = m_class ? m_class->m_azRtti : nullptr; - + if (description.m_traits & (AZ::BehaviorParameter::TR_POINTER | AZ::BehaviorParameter::TR_REFERENCE)) { parameter.m_value = &m_pointer; @@ -2280,7 +2320,7 @@ namespace ScriptCanvas else { parameter.m_value = ModResultAddress(); - + if (!parameter.m_value) { return AZ::Failure(AZStd::string("nowhere to go for the for behavior context result")); @@ -2333,7 +2373,7 @@ namespace ScriptCanvas return AZ::Failure(AZStd::string::format("Cannot create a BehaviorValueParameter of type %s", description.m_name)); } - + bool Datum::ToString(Data::StringType& result) const { switch (GetType().GetType()) @@ -2422,11 +2462,11 @@ namespace ScriptCanvas result = AZStd::string::format("", Data::GetName(m_type).data()); return false; } - + AZStd::string Datum::ToStringAABB(const Data::AABBType& aabb) const { return AZStd::string::format - ( "(Min: %s, Max: %s)" + ("(Min: %s, Max: %s)" , ToStringVector3(aabb.GetMin()).c_str() , ToStringVector3(aabb.GetMax()).c_str()); } @@ -2466,15 +2506,15 @@ namespace ScriptCanvas } } } - + stringOut = ""; return false; } - + AZStd::string Datum::ToStringMatrix3x3(const AZ::Matrix3x3& m) const { return AZStd::string::format - ( "(%s, %s, %s)" + ("(%s, %s, %s)" , ToStringVector3(m.GetColumn(0)).c_str() , ToStringVector3(m.GetColumn(1)).c_str() , ToStringVector3(m.GetColumn(2)).c_str()); @@ -2484,7 +2524,7 @@ namespace ScriptCanvas AZStd::string Datum::ToStringMatrix4x4(const AZ::Matrix4x4& m) const { return AZStd::string::format - ( "(%s, %s, %s, %s)" + ("(%s, %s, %s, %s)" , ToStringVector4(m.GetColumn(0)).c_str() , ToStringVector4(m.GetColumn(1)).c_str() , ToStringVector4(m.GetColumn(2)).c_str() @@ -2495,7 +2535,7 @@ namespace ScriptCanvas AZStd::string Datum::ToStringOBB(const Data::OBBType& obb) const { return AZStd::string::format - ( "(Position: %s, AxisX: %s, AxisY: %s, AxisZ: %s, halfLengthX: %.7f, halfLengthY: %.7f, halfLengthZ: %.7f)" + ("(Position: %s, AxisX: %s, AxisY: %s, AxisZ: %s, halfLengthX: %.7f, halfLengthY: %.7f, halfLengthZ: %.7f)" , ToStringVector3(obb.GetPosition()).c_str() , ToStringVector3(obb.GetAxisX()).c_str() , ToStringVector3(obb.GetAxisY()).c_str() @@ -2514,7 +2554,7 @@ namespace ScriptCanvas { AZ::Vector3 eulerRotation = AZ::ConvertTransformToEulerDegrees(AZ::Transform::CreateFromQuaternion(source)); return AZStd::string::format - ( "(Pitch: %5.2f, Roll: %5.2f, Yaw: %5.2f)" + ("(Pitch: %5.2f, Roll: %5.2f, Yaw: %5.2f)" , static_cast(eulerRotation.GetX()) , static_cast(eulerRotation.GetY()) , static_cast(eulerRotation.GetZ())); @@ -2527,35 +2567,35 @@ namespace ScriptCanvas float scale = copy.ExtractUniformScale(); AZ::Vector3 rotation = AZ::ConvertTransformToEulerDegrees(copy); return AZStd::string::format - ( "(Position: X: %f, Y: %f, Z: %f," - " Rotation: X: %f, Y: %f, Z: %f," - " Scale: %f)" - , static_cast(pos.GetX()), static_cast(pos.GetY()), static_cast(pos.GetZ()) - , static_cast(rotation.GetX()), static_cast(rotation.GetY()), static_cast(rotation.GetZ()) - , scale); + ("(Position: X: %f, Y: %f, Z: %f," + " Rotation: X: %f, Y: %f, Z: %f," + " Scale: %f)" + , static_cast(pos.GetX()), static_cast(pos.GetY()), static_cast(pos.GetZ()) + , static_cast(rotation.GetX()), static_cast(rotation.GetY()), static_cast(rotation.GetZ()) + , scale); } AZStd::string Datum::ToStringVector2(const AZ::Vector2& source) const { return AZStd::string::format - ( "(X: %f, Y: %f)" + ("(X: %f, Y: %f)" , source.GetX() , source.GetY()); } - + AZStd::string Datum::ToStringVector3(const AZ::Vector3& source) const { return AZStd::string::format - ( "(X: %f, Y: %f, Z: %f)" + ("(X: %f, Y: %f, Z: %f)" , static_cast(source.GetX()) , static_cast(source.GetY()) , static_cast(source.GetZ())); } - + AZStd::string Datum::ToStringVector4(const AZ::Vector4& source) const { return AZStd::string::format - ("(X: %f, Y: %f, Z: %f, W: %f)" + ("(X: %f, Y: %f, Z: %f, W: %f)" , static_cast(source.GetX()) , static_cast(source.GetY()) , static_cast(source.GetZ()) @@ -2608,5 +2648,4 @@ namespace ScriptCanvas { return datum != nullptr && !datum->Empty(); } - } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h index 0c6912afe8..00500b4035 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -9,8 +9,8 @@ #include #include -#include #include +#include #include #include #include @@ -59,7 +59,7 @@ namespace ScriptCanvas Datum(BehaviorContextResultTag, const AZ::BehaviorParameter& resultType); Datum(const AZStd::string& behaviorClassName, eOriginality originality); Datum(const AZ::BehaviorValueParameter& value); - + void ReconfigureDatumTo(Datum&& object); void ReconfigureDatumTo(const Datum& object); @@ -204,18 +204,18 @@ namespace ScriptCanvas { static_assert(!AZStd::is_pointer::value, "no pointer types in the Datum::GetAsHelper"); - if (datum.m_storage.empty()) + if (datum.m_storage.value.empty()) { // rare, but can be caused by removals or problems with reflection to BehaviorContext, so must be checked return nullptr; } else if (datum.m_type.GetType() == Data::eType::BehaviorContextObject) { - return (*AZStd::any_cast(&datum.m_storage))->CastConst(); + return (*AZStd::any_cast(&datum.m_storage.value))->CastConst(); } else { - return AZStd::any_cast(&datum.m_storage); + return AZStd::any_cast(&datum.m_storage.value); } } }; @@ -253,12 +253,12 @@ namespace ScriptCanvas // eOriginality records the graph source of the object eOriginality m_originality = eOriginality::Copy; // storage for the datum, regardless of ScriptCanvas::Data::Type - AZStd::any m_storage; + RuntimeVariable m_storage; - // This contains the editor label for m_storage. + // This contains the editor label for m_storage.value. AZStd::string m_datumLabel; - // This contains the editor visibility for m_storage. + // This contains the editor visibility for m_storage.value. AZ::Crc32 m_visibility{ AZ::Edit::PropertyVisibility::ShowChildrenOnly }; // storage for implicit conversions, when needed AZStd::any m_conversionStorage; @@ -304,7 +304,7 @@ namespace ScriptCanvas bool InitializeCRC(const void* source); bool InitializeEntityID(const void* source); - + bool InitializeNamedEntityID(const void* source); bool InitializeMatrix3x3(const void* source); @@ -384,7 +384,7 @@ namespace ScriptCanvas bool Datum::Empty() const { - return m_storage.empty() || GetValueAddress() == nullptr; + return m_storage.value.empty() || GetValueAddress() == nullptr; } template @@ -492,7 +492,7 @@ namespace ScriptCanvas { if (Data::IsValueType(m_type)) { - m_storage = value; + m_storage.value = value; return true; } else diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp index abd4cf1bb7..7b9c4bc048 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Graph.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -136,10 +136,7 @@ namespace ScriptCanvas { if (nodeEntity) { - if (nodeEntity->GetState() == AZ::Entity::State::Constructed) - { - nodeEntity->Init(); - } + ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(nodeEntity); if (auto* node = AZ::EntityUtils::FindFirstDerivedComponent(nodeEntity)) { @@ -155,10 +152,7 @@ namespace ScriptCanvas { if (connectionEntity) { - if (connectionEntity->GetState() == AZ::Entity::State::Constructed) - { - connectionEntity->Init(); - } + ScriptCanvas::ScopedAuxiliaryEntityHandler entityHandler(connectionEntity); } } @@ -169,7 +163,7 @@ namespace ScriptCanvas { if (m_isFunctionGraph) { - return true; + return true; } return false; @@ -418,7 +412,7 @@ namespace ScriptCanvas void Graph::ValidateVariables(ValidationResults& validationResults) { const VariableData* variableData = GetVariableData(); - + if (!variableData) { return; @@ -440,7 +434,7 @@ namespace ScriptCanvas { errorDescription = AZStd::string::format("Variable %s has an invalid type %s.", GetVariableName(variableId).data(), variableType.GetAZType().ToString().c_str()); } - } + } else if (variableType == Data::Type::Invalid()) { errorDescription = AZStd::string::format("Variable %s has an invalid type.", GetVariableName(variableId).data()); @@ -502,7 +496,7 @@ namespace ScriptCanvas { m_graphData.m_nodes.emplace(nodeEntity); m_nodeMapping[nodeId] = node; - + node->SetOwningScriptCanvasId(m_scriptCanvasId); node->Configure(); GraphNotificationBus::Event(m_scriptCanvasId, &GraphNotifications::OnNodeAdded, nodeId); @@ -523,17 +517,17 @@ namespace ScriptCanvas if (node) { auto entry = m_graphData.m_nodes.find(node->GetEntity()); - if (entry != m_graphData.m_nodes.end()) - { - m_nodeMapping.erase(nodeId); - m_graphData.m_nodes.erase(entry); - GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnNodeRemoved, nodeId); + if (entry != m_graphData.m_nodes.end()) + { + m_nodeMapping.erase(nodeId); + m_graphData.m_nodes.erase(entry); + GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnNodeRemoved, nodeId); - RemoveDependentAsset(nodeId); - return true; + RemoveDependentAsset(nodeId); + return true; + } } } - } return false; } @@ -1036,17 +1030,17 @@ namespace ScriptCanvas } } -// for (auto connectionId : removableConnections) -// { -// DisconnectById(connectionId); -// } + // for (auto connectionId : removableConnections) + // { + // DisconnectById(connectionId); + // } if (!removableConnections.empty()) { // RefreshConnectionValidity(warnOnRemoval); } } - + void Graph::OnEntityActivated(const AZ::EntityId&) { } @@ -1075,7 +1069,7 @@ namespace ScriptCanvas AZ::Data::AssetManager::Instance().GetAsset(scriptEventNode->GetAssetId(), AZ::Data::AssetLoadBehavior::Default); } } - + m_batchAddingData = false; GraphNotificationBus::Event(GetScriptCanvasId(), &GraphNotifications::OnBatchAddComplete); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Debugger/Debugger.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Debugger/Debugger.cpp index 1e3ba13aaf..4ec5c31ca5 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Debugger/Debugger.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Debugger/Debugger.cpp @@ -756,10 +756,9 @@ namespace ScriptCanvas { auto runtimeComponent = (*graphIter); - if (graphIdentifier.m_assetId.m_guid == runtimeComponent->GetAsset().GetId().m_guid) + if (graphIdentifier.m_assetId.m_guid == runtimeComponent->GetRuntimeDataOverrides().m_runtimeAsset.GetId().m_guid) { // TODO: Gate on ComponentId - // \todo chcurran restore this functionality // runtimeComponent->SetIsGraphObserved(observedState); runtimeComponents.erase(graphIter); break; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp index af8a2d5f15..292a9490b8 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp @@ -1,12 +1,13 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include +#include #include #include #include @@ -19,13 +20,13 @@ namespace ExecutionContextCpp { - void TypeCopy(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs) + void CopyTypeInformationOnly(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs) { lhs.m_typeId = rhs.m_typeId; lhs.m_azRtti = rhs.m_azRtti; } - void ValueCopy(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs) + void CopyTypeAndValueSource(AZ::BehaviorValueParameter& lhs, const AZ::BehaviorValueParameter& rhs) { lhs.m_typeId = rhs.m_typeId; lhs.m_azRtti = rhs.m_azRtti; @@ -37,87 +38,102 @@ namespace ScriptCanvas { namespace Execution { - ActivationData::ActivationData(const RuntimeComponent& component, ActivationInputArray& storage) - : entityId(component.GetEntityId()) - , variableOverrides(component.GetVariableOverrides()) - , runtimeData(component.GetAsset()->GetData()) + ActivationData::ActivationData(const RuntimeDataOverrides& variableOverrides, ActivationInputArray& storage) + : variableOverrides(variableOverrides) + , runtimeData(variableOverrides.m_runtimeAsset->GetData()) , storage(storage) {} - ActivationData::ActivationData(const AZ::EntityId entityId, const VariableData& variableOverrides, const RuntimeData& runtimeData, ActivationInputArray& storage) - : entityId(entityId) - , variableOverrides(variableOverrides) - , runtimeData(runtimeData) - , storage(storage) - {} + const void* ActivationData::GetVariableSource(size_t index, size_t& overrideIndexTracker) const + { + if (variableOverrides.m_variableIndices[index]) + { + return AZStd::any_cast(&variableOverrides.m_variables[overrideIndexTracker++].value); + } + else + { + return runtimeData.m_input.m_variables[index].second.GetAsDanger(); + } + } - ActivationInputRange Context::CreateActivateInputRange(ActivationData& activationData) + ActivationInputRange Context::CreateActivateInputRange(ActivationData& activationData, [[maybe_unused]] const AZ::EntityId& forSliceSupportOnly) { const RuntimeData& runtimeData = activationData.runtimeData; ActivationInputRange rangeOut = runtimeData.m_activationInputRange; rangeOut.inputs = activationData.storage.begin(); - + AZ_Assert(rangeOut.totalCount <= activationData.storage.size(), "Too many initial arguments for activation. " "Consider increasing size, source of ActivationInputArray, or breaking up the source graph"); - // nodeables + // nodeables - until the optimization is required, every instance gets their own copy { auto sourceVariableIter = runtimeData.m_activationInputRange.inputs; const auto sourceVariableSentinel = runtimeData.m_activationInputRange.inputs + runtimeData.m_activationInputRange.nodeableCount; auto destVariableIter = rangeOut.inputs; for (; sourceVariableIter != sourceVariableSentinel; ++sourceVariableIter, ++destVariableIter) { - ExecutionContextCpp::ValueCopy(*destVariableIter, *sourceVariableIter); + ExecutionContextCpp::CopyTypeAndValueSource(*destVariableIter, *sourceVariableIter); } } - // (possibly overridden) variables + // (possibly overridden) variables, only the overrides are saved in on the component, otherwise they are taken from the runtime asset { auto sourceVariableIter = runtimeData.m_activationInputRange.inputs + runtimeData.m_activationInputRange.nodeableCount; auto destVariableIter = rangeOut.inputs + runtimeData.m_activationInputRange.nodeableCount; - for (auto& idDatumPair : runtimeData.m_input.m_variables) + size_t overrideIndexTracker = 0; + const size_t sentinel = runtimeData.m_input.m_variables.size(); + for (size_t index = 0; index != sentinel; ++index, ++destVariableIter, ++sourceVariableIter) { - ExecutionContextCpp::TypeCopy(*destVariableIter, *sourceVariableIter); - - auto variableOverride = activationData.variableOverrides.FindVariable(idDatumPair.first); - const Datum* datum = variableOverride ? variableOverride->GetDatum() : &idDatumPair.second; - destVariableIter->m_value = const_cast(datum->GetAsDanger()); - - ++destVariableIter; - ++sourceVariableIter; + ExecutionContextCpp::CopyTypeInformationOnly(*destVariableIter, *sourceVariableIter); + destVariableIter->m_value = const_cast(activationData.GetVariableSource(index, overrideIndexTracker)); } } - // (must always be re-mapped) EntityId - if (!runtimeData.m_input.m_entityIds.empty()) + // (always overridden) EntityIds { - AZ::SliceComponent::EntityIdToEntityIdMap loadedEntityIdMap; - AzFramework::EntityContextId owningContextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::EntityIdContextQueryBus::EventResult(owningContextId, activationData.entityId, &AzFramework::EntityIdContextQueries::GetOwningContextId); - if (!owningContextId.IsNull()) + bool prefabSystemEnabled = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); + + if (prefabSystemEnabled) { - AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(loadedEntityIdMap, owningContextId, &AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetLoadedEntityIdMap); - } + AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs + + runtimeData.m_activationInputRange.nodeableCount + + runtimeData.m_activationInputRange.variableCount; - AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs - + runtimeData.m_activationInputRange.nodeableCount - + runtimeData.m_activationInputRange.variableCount; + const auto entityIdTypeId = azrtti_typeid(); - const auto entityIdTypeId = azrtti_typeid(); - for (auto& idEntityPair : runtimeData.m_input.m_entityIds) - { - destVariableIter->m_typeId = entityIdTypeId; - destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); - auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); - - if (auto variableOverride = activationData.variableOverrides.FindVariable(idEntityPair.first)) + for (auto& entityId : activationData.variableOverrides.m_entityIds) { - *entityIdValuePtr = *variableOverride->GetDatum()->GetAs(); + destVariableIter->m_typeId = entityIdTypeId; + destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); + auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); + *entityIdValuePtr = entityId; + ++destVariableIter; } - else + } + else + { + AZ::SliceComponent::EntityIdToEntityIdMap loadedEntityIdMap; + AzFramework::EntityContextId owningContextId = AzFramework::EntityContextId::CreateNull(); + AzFramework::EntityIdContextQueryBus::EventResult(owningContextId, forSliceSupportOnly, &AzFramework::EntityIdContextQueries::GetOwningContextId); + if (!owningContextId.IsNull()) { - auto iter = loadedEntityIdMap.find(idEntityPair.second); + AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(loadedEntityIdMap, owningContextId, &AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetLoadedEntityIdMap); + } + + AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs + + runtimeData.m_activationInputRange.nodeableCount + + runtimeData.m_activationInputRange.variableCount; + + const auto entityIdTypeId = azrtti_typeid(); + for (auto& entityId : activationData.variableOverrides.m_entityIds) + { + destVariableIter->m_typeId = entityIdTypeId; + destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); + auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); + + auto iter = loadedEntityIdMap.find(entityId); if (iter != loadedEntityIdMap.end()) { *entityIdValuePtr = iter->second; @@ -126,9 +142,10 @@ namespace ScriptCanvas { *entityIdValuePtr = Data::EntityIDType(); } - } - ++destVariableIter; + *entityIdValuePtr = entityId; + ++destVariableIter; + } } } @@ -156,7 +173,7 @@ namespace ScriptCanvas for (auto& idDatumPair : runtimeData.m_input.m_variables) { - const Datum* datum = &idDatumPair.second; + const Datum* datum = &idDatumPair.second; AZ::BehaviorValueParameter bvp; bvp.m_typeId = datum->GetType().GetAZType(); const auto classIter(behaviorContext.m_typeToClassMap.find(bvp.m_typeId)); @@ -214,6 +231,6 @@ namespace ScriptCanvas Execution::InterpretedUnloadData(runtimeData); } - } + } -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.h index ed55af7286..c697bf71f6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -12,9 +12,9 @@ namespace ScriptCanvas { class RuntimeComponent; - class VariableData; struct RuntimeData; + struct RuntimeDataOverrides; namespace Execution { @@ -22,15 +22,15 @@ namespace ScriptCanvas struct ActivationData { - ActivationData(const RuntimeComponent& component, ActivationInputArray& storage); - ActivationData(const AZ::EntityId entityId, const VariableData& variableOverrides, const RuntimeData& runtimeData, ActivationInputArray& storage); - - const AZ::EntityId entityId; - const VariableData& variableOverrides; + const RuntimeDataOverrides& variableOverrides; const RuntimeData& runtimeData; ActivationInputArray& storage; + + ActivationData(const RuntimeDataOverrides& variableOverrides, ActivationInputArray& storage); + + const void* GetVariableSource(size_t index, size_t& overrideIndexTracker) const; }; - + struct ActivationInputRange { AZ::BehaviorValueParameter* inputs = nullptr; @@ -47,7 +47,7 @@ namespace ScriptCanvas AZ_TYPE_INFO(Context, "{2C137581-19F4-42EB-8BF3-14DBFBC02D8D}"); AZ_CLASS_ALLOCATOR(Context, AZ::SystemAllocator, 0); - static ActivationInputRange CreateActivateInputRange(ActivationData& activationData); + static ActivationInputRange CreateActivateInputRange(ActivationData& activationData, const AZ::EntityId& forSliceSupportOnly); static void InitializeActivationData(RuntimeData& runtimeData); static void UnloadData(RuntimeData& runtimeData); @@ -56,5 +56,5 @@ namespace ScriptCanvas static void IntializeStaticCloners(RuntimeData& runtimeData, AZ::BehaviorContext& behaviorContext); }; - } -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp index fb9ba1afb0..aebb3ed20e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -27,34 +27,34 @@ namespace ScriptCanvas ExecutionState::ExecutionState(const ExecutionStateConfig& config) : m_component(&config.component) {} - + ExecutionStatePtr ExecutionState::Create(const ExecutionStateConfig& config) { Grammar::ExecutionStateSelection selection = config.runtimeData.m_input.m_executionSelection; switch (selection) { - case Grammar::InterpretedPure: + case Grammar::ExecutionStateSelection::InterpretedPure: return AZStd::make_shared(config); - - case Grammar::InterpretedPureOnGraphStart: + + case Grammar::ExecutionStateSelection::InterpretedPureOnGraphStart: return AZStd::make_shared(config); - case Grammar::InterpretedObject: + case Grammar::ExecutionStateSelection::InterpretedObject: return AZStd::make_shared(config); - case Grammar::InterpretedObjectOnGraphStart: + case Grammar::ExecutionStateSelection::InterpretedObjectOnGraphStart: return AZStd::make_shared(config); - + default: AZ_Assert(false, "Unsupported ScriptCanvas execution selection"); return nullptr; } } - + AZ::Data::AssetId ExecutionState::GetAssetId() const { - return m_component->GetAsset().GetId(); + return m_component->GetRuntimeDataOverrides().m_runtimeAsset.GetId(); } AZ::EntityId ExecutionState::GetEntityId() const @@ -82,9 +82,9 @@ namespace ScriptCanvas return m_component->GetScriptCanvasId(); } - const VariableData& ExecutionState::GetVariableOverrides() const + const RuntimeDataOverrides& ExecutionState::GetRuntimeDataOverrides() const { - return m_component->GetVariableOverrides(); + return m_component->GetRuntimeDataOverrides(); } void ExecutionState::Reflect(AZ::ReflectContext* reflectContext) @@ -95,7 +95,7 @@ namespace ScriptCanvas ->Method("GetEntityId", &ExecutionState::GetEntityId) ->Method("GetScriptCanvasId", &ExecutionState::GetScriptCanvasId) ->Method("ToString", &ExecutionState::ToString) - ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString) + ->Attribute(AZ::Script::Attributes::Operator, AZ::Script::Attributes::OperatorType::ToString) ; } @@ -116,7 +116,7 @@ namespace ScriptCanvas { return shared_from_this(); } - + AZStd::string ExecutionState::ToString() const { return AZStd::string::format("ExecutionState[%p]", this); @@ -132,4 +132,4 @@ namespace ScriptCanvas return ExecutionStateWeakConstPtr(this); } -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.h index 0cb51b028e..12c74f39eb 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -37,7 +37,7 @@ namespace ScriptCanvas ExecutionStateConfig(AZ::Data::Asset asset, RuntimeComponent& component); }; - + class ExecutionState : public AZStd::enable_shared_from_this { @@ -50,7 +50,7 @@ namespace ScriptCanvas static void Reflect(AZ::ReflectContext* reflectContext); const RuntimeComponent* m_component = nullptr; - + ExecutionState(const ExecutionStateConfig& config); virtual ~ExecutionState() = default; @@ -71,7 +71,7 @@ namespace ScriptCanvas AZ::EntityId GetScriptCanvasId() const; - const VariableData& GetVariableOverrides() const; + const RuntimeDataOverrides& GetRuntimeDataOverrides() const; virtual void Initialize() = 0; @@ -88,4 +88,4 @@ namespace ScriptCanvas ExecutionStateWeakConstPtr WeakFromThisConst() const; }; -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp index 9730d52289..3806e7a3c7 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionInterpretedAPI.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -176,7 +176,7 @@ namespace ExecutionInterpretedAPICpp // Lua: AZStd::pair multipleResults = ScriptCanvas::BehaviorContextUtils::ConstructTupleGetContext(typeId); AZ_Assert(multipleResults.first, "failure to construct a tuple by typeid from behavior context"); - AZ::BehaviorValueParameter parameter; + AZ::BehaviorValueParameter parameter; parameter.m_value = multipleResults.first; parameter.m_typeId = typeId; AZ::StackPush(lua, multipleResults.second, parameter); @@ -253,7 +253,7 @@ namespace ScriptCanvas break; } } - + void SetInterpretedExecutionModeDebug() { AZ::ScriptContext* scriptContext{}; @@ -314,7 +314,7 @@ namespace ScriptCanvas { using namespace ExecutionInterpretedAPICpp; static_assert(sizeof(AZ::Uuid) == k_UuidSize, "size of uuid has changed"); - + AZStd::string fastString; fastString.resize(k_StringFastSize); char* fastDigit = fastString.begin(); @@ -338,7 +338,7 @@ namespace ScriptCanvas AZ_Assert(string, "string argument must not be null"); AZ_Assert(strlen(string) == k_StringFastSize, "invalid length of string, fast format must be: 0123456789ABCDEF0123456789ABCDEF"); const char* current = string; - + AZ::Uuid id; auto data = id.begin(); auto sentinel = id.end(); @@ -358,8 +358,7 @@ namespace ScriptCanvas ++current; *data = (value0 << 4) | value1; - } - while ((++data) != sentinel); + } while ((++data) != sentinel); return id; } @@ -370,7 +369,6 @@ namespace ScriptCanvas /** Here is the function in Lua for easier reading - function OverrideNodeableMetatable(userdata, class_mt) local proxy = setmetatable({}, class_mt) -- class_mt from the user graph definition local instance_mt = { @@ -388,18 +386,16 @@ namespace ScriptCanvas --]] return setmetatable(userdata instance_mt) -- can't be done from Lua end - --[[ userdata to Nodeable before: getmetatable(userdata).__index == Nodeable - + userdata to Nodeable after: local override_mt = getmetatable(userdata) local proxy = override_mt.__index local SubGraph = getmetatable(proxy).__index getmetatable(SubGraph.__index) == Nodeable) --]] - */ // \note: all other metamethods ignored for now @@ -504,7 +500,7 @@ namespace ScriptCanvas 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_isnumber(lua, 2), "CallExecutionOut: Error in compiled lua file, 2nd argument to SetExecutionOut is not a number"); - Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, 1); + Nodeable* nodeable = AZ::ScriptValue::StackRead(lua, 1); size_t index = aznumeric_caster(lua_tointeger(lua, 2)); nodeable->CallOut(index, nullptr, nullptr, argsCount - 2); // Lua: results... @@ -568,7 +564,7 @@ namespace ScriptCanvas { const int handlerIndex = lua_gettop(lua) - argCount; lua_pushcfunction(lua, &ExecutionInterpretedAPICpp::ErrorHandler); - lua_insert(lua, handlerIndex); + lua_insert(lua, handlerIndex); int result = lua_pcall(lua, argCount, returnValueCount, handlerIndex); lua_remove(lua, handlerIndex); return result; @@ -581,7 +577,7 @@ namespace ScriptCanvas AZ_Assert(lua_isuserdata(lua, -3), "Error in compiled lua file, 1st argument to SetExecutionOut is not userdata (Nodeable)"); 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)"); + 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"); size_t index = aznumeric_caster(lua_tointeger(lua, -2)); @@ -680,9 +676,9 @@ namespace ScriptCanvas struct DependencyConstructionPack { ExecutionStateInterpreted* executionState; - AZStd::vector>* dependentAssets; - const size_t dependentAssetsIndex; - RuntimeData& runtimeData; + AZStd::vector* dependencies; + const size_t dependenciesIndex; + RuntimeDataOverrides& runtimeOverrides; }; DependencyConstructionPack UnpackDependencyConstructionArgsSanitize(lua_State* lua) @@ -690,27 +686,26 @@ namespace ScriptCanvas auto executionState = AZ::ScriptValue::StackRead(lua, 1); AZ_Assert(executionState, "Error in compiled lua file, 1st argument to UnpackDependencyArgs is not an ExecutionStateInterpreted"); AZ_Assert(lua_islightuserdata(lua, 2), "Error in compiled lua file, 2nd argument to UnpackDependencyArgs is not userdata (AZStd::vector>*), but a :%s", lua_typename(lua, 2)); - auto dependentAssets = reinterpret_cast>*>(lua_touserdata(lua, 2)); + auto dependentOverrides = reinterpret_cast*>(lua_touserdata(lua, 2)); AZ_Assert(lua_isinteger(lua, 3), "Error in compiled Lua file, 3rd argument to UnpackDependencyArgs is not a number"); - const size_t dependentAssetsIndex = aznumeric_caster(lua_tointeger(lua, 3)); - - return DependencyConstructionPack{ executionState, dependentAssets, dependentAssetsIndex, (*dependentAssets)[dependentAssetsIndex].Get()->m_runtimeData }; + const size_t dependencyIndex = aznumeric_caster(lua_tointeger(lua, 3)); + return DependencyConstructionPack{ executionState, dependentOverrides, dependencyIndex, (*dependentOverrides)[dependencyIndex] }; } int Unpack(lua_State* lua, DependencyConstructionPack& args) { ActivationInputArray storage; - ActivationData data(args.executionState->GetEntityId(), args.executionState->GetVariableOverrides(), args.runtimeData, storage); - ActivationInputRange range = Execution::Context::CreateActivateInputRange(data); + ActivationData data(args.runtimeOverrides, storage); + ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, args.executionState->GetEntityId()); PushActivationArgs(lua, range.inputs, range.totalCount); return range.totalCount; } int UnpackDependencyConstructionArgs(lua_State* lua) { - // Lua: executionState, dependentAssets, dependentAssetsIndex + // Lua: executionState, dependent overrides, index into dependent overrides DependencyConstructionPack pack = UnpackDependencyConstructionArgsSanitize(lua); - lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&pack.runtimeData.m_requiredAssets))); + lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&pack.runtimeOverrides.m_dependencies))); return 1 + Unpack(lua, pack); } @@ -720,6 +715,5 @@ namespace ScriptCanvas DependencyConstructionPack constructionArgs = UnpackDependencyConstructionArgsSanitize(lua); return Unpack(lua, constructionArgs); } - } - -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp index 27377157be..d7cc05cf1b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -20,6 +20,7 @@ namespace ExecutionStateInterpretedCpp AZ::Data::Asset GetSubgraphAssetForDebug(const AZ::Data::AssetId& id) { + // #functions2 this may have to be made recursive auto asset = AZ::Data::AssetManager::Instance().GetAsset(id, AZ::Data::AssetLoadBehavior::PreLoad); asset.BlockUntilLoadComplete(); return asset; @@ -32,7 +33,7 @@ namespace ScriptCanvas : ExecutionState(config) , m_interpretedAsset(config.runtimeData.m_script) {} - + void ExecutionStateInterpreted::ClearLuaRegistryIndex() { m_luaRegistryIndex = LUA_NOREF; @@ -40,8 +41,8 @@ namespace ScriptCanvas const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolIn(size_t index) const { - return index < m_component->GetAssetData().m_debugMap.m_ins.size() - ? &(m_component->GetAssetData().m_debugMap.m_ins[index]) + return index < m_component->GetRuntimeAssetData().m_debugMap.m_ins.size() + ? &(m_component->GetRuntimeAssetData().m_debugMap.m_ins[index]) : nullptr; } @@ -55,8 +56,8 @@ namespace ScriptCanvas const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolOut(size_t index) const { - return index < m_component->GetAssetData().m_debugMap.m_outs.size() - ? &(m_component->GetAssetData().m_debugMap.m_outs[index]) + return index < m_component->GetRuntimeAssetData().m_debugMap.m_outs.size() + ? &(m_component->GetRuntimeAssetData().m_debugMap.m_outs[index]) : nullptr; } @@ -70,8 +71,8 @@ namespace ScriptCanvas const Grammar::DebugExecution* ExecutionStateInterpreted::GetDebugSymbolReturn(size_t index) const { - return index < m_component->GetAssetData().m_debugMap.m_returns.size() - ? &(m_component->GetAssetData().m_debugMap.m_returns[index]) + return index < m_component->GetRuntimeAssetData().m_debugMap.m_returns.size() + ? &(m_component->GetRuntimeAssetData().m_debugMap.m_returns[index]) : nullptr; } @@ -85,8 +86,8 @@ namespace ScriptCanvas const Grammar::DebugDataSource* ExecutionStateInterpreted::GetDebugSymbolVariableChange(size_t index) const { - return index < m_component->GetAssetData().m_debugMap.m_variables.size() - ? &(m_component->GetAssetData().m_debugMap.m_variables[index]) + return index < m_component->GetRuntimeAssetData().m_debugMap.m_variables.size() + ? &(m_component->GetRuntimeAssetData().m_debugMap.m_variables[index]) : nullptr; } @@ -148,5 +149,4 @@ namespace ScriptCanvas luaL_unref(m_luaState, LUA_REGISTRYINDEX, m_luaRegistryIndex); m_luaRegistryIndex = LUA_NOREF; } - -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp index 86e2b6d7fd..5dbc35236f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPerActivation.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -19,7 +19,7 @@ namespace ScriptCanvas ExecutionStateInterpretedPerActivation::ExecutionStateInterpretedPerActivation(const ExecutionStateConfig& config) : ExecutionStateInterpreted(config) {} - + ExecutionStateInterpretedPerActivation::~ExecutionStateInterpretedPerActivation() { if (m_deactivationRequired) @@ -45,15 +45,15 @@ namespace ScriptCanvas AZ::Internal::LuaClassToStack(lua, this, azrtti_typeid(), AZ::ObjectToLua::ByReference, AZ::AcquisitionOnPush::None); // Lua: graph_VM, graph_VM['new'], userdata Execution::ActivationInputArray storage; - Execution::ActivationData data(*m_component, storage); - Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data); + Execution::ActivationData data(m_component->GetRuntimeDataOverrides(), storage); + Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, m_component->GetEntityId()); if (range.requiresDependencyConstructionParameters) { - lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&data.runtimeData.m_requiredAssets))); - // Lua: graph_VM, graph_VM['new'], userdata, dependencies + lua_pushlightuserdata(lua, const_cast(reinterpret_cast(&data.variableOverrides.m_dependencies))); + // Lua: graph_VM, graph_VM['new'], userdata, runtimeDataOverrides Execution::PushActivationArgs(lua, range.inputs, range.totalCount); - // Lua: graph_VM, graph_VM['new'], userdata, dependencies, args... + // Lua: graph_VM, graph_VM['new'], userdata, runtimeDataOverrides, args... AZ::Internal::LuaSafeCall(lua, aznumeric_caster(2 + range.totalCount), 1); } else @@ -139,5 +139,4 @@ namespace ScriptCanvas ; } } - -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp index 20f5a2126e..368ceccf95 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpretedPure.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -21,7 +21,7 @@ namespace ScriptCanvas void ExecutionStateInterpretedPure::Execute() {} - + void ExecutionStateInterpretedPure::Initialize() {} @@ -52,8 +52,8 @@ namespace ScriptCanvas AZ::Internal::LuaClassToStack(lua, this, azrtti_typeid(), AZ::ObjectToLua::ByReference, AZ::AcquisitionOnPush::None); // Lua: graph_VM, graph_VM['k_OnGraphStartFunctionName'], userdata Execution::ActivationInputArray storage; - Execution::ActivationData data(*m_component, storage); - Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data); + Execution::ActivationData data(m_component->GetRuntimeDataOverrides(), storage); + Execution::ActivationInputRange range = Execution::Context::CreateActivateInputRange(data, m_component->GetEntityId()); Execution::PushActivationArgs(lua, range.inputs, range.totalCount); // Lua: graph_VM, graph_VM['k_OnGraphStartFunctionName'], userdata, args... const int result = Execution::InterpretedSafeCall(lua, aznumeric_caster(1 + range.totalCount), 0); @@ -78,4 +78,4 @@ namespace ScriptCanvas ; } } -} +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp index 94cb258c95..d5ba635838 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -24,9 +24,12 @@ namespace RuntimeComponentCpp { - enum Version + enum class RuntimeComponentVersion : unsigned int { ForceAssetPreloads = 5, + AddRuntimeDataOverrides, + PrefabSupport, + RemoveRuntimeAsset, // add description above Current, @@ -40,17 +43,11 @@ namespace ScriptCanvas return GraphInfo(scriptCanvasId, graphIdentifier); } - DatumValue CreateDatumValue(ScriptCanvasId /*scriptCanvasId*/, const GraphVariable& variable) + DatumValue CreateDatumValue([[maybe_unused]] ScriptCanvasId scriptCanvasId, const GraphVariable& variable) { return DatumValue::Create(GraphVariable((*variable.GetDatum()), variable.GetVariableId())); } - RuntimeComponent::RuntimeComponent(AZ::Data::Asset runtimeAsset) - : m_runtimeAsset(runtimeAsset) - { - m_runtimeAsset.SetAutoLoadBehavior(AZ::Data::AssetLoadBehavior::PreLoad); - } - void RuntimeComponent::Activate() { InitializeExecution(); @@ -66,18 +63,13 @@ namespace ScriptCanvas 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()); + SCRIPT_CANVAS_PERFORMANCE_SCOPE_EXECUTION(m_executionState->GetScriptCanvasId(), m_runtimeOverrides.m_runtimeAsset.GetId()); m_executionState->Execute(); } - const AZ::Data::Asset& RuntimeComponent::GetAsset() const + const RuntimeData& RuntimeComponent::GetRuntimeAssetData() const { - return m_runtimeAsset; - } - - const RuntimeData& RuntimeComponent::GetAssetData() const - { - return m_runtimeAsset->GetData(); + return m_runtimeOverrides.m_runtimeAsset->GetData(); } ExecutionMode RuntimeComponent::GetExecutionMode() const @@ -87,7 +79,7 @@ namespace ScriptCanvas GraphIdentifier RuntimeComponent::GetGraphIdentifier() const { - return GraphIdentifier(AZ::Data::AssetId(m_runtimeAsset.GetId().m_guid, 0), 0); + return GraphIdentifier(AZ::Data::AssetId(m_runtimeOverrides.m_runtimeAsset.GetId().m_guid, 0), 0); } AZ::EntityId RuntimeComponent::GetScriptCanvasId() const @@ -95,37 +87,43 @@ namespace ScriptCanvas return m_scriptCanvasId; } - const VariableData& RuntimeComponent::GetVariableOverrides() const + const RuntimeDataOverrides& RuntimeComponent::GetRuntimeDataOverrides() const { - return m_variableOverrides; + return m_runtimeOverrides; + } + + void RuntimeComponent::SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData) + { + m_runtimeOverrides = overrideData; + m_runtimeOverrides.EnforcePreloadBehavior(); } void RuntimeComponent::Init() { m_scriptCanvasId = AZ::Entity::MakeId(); - AZ_Assert(m_runtimeAsset.GetAutoLoadBehavior() == AZ::Data::AssetLoadBehavior::PreLoad, "RuntimeComponent::m_runtimeAsset Auto load behavior MUST be set to AZ::Data::AssetLoadBehavior::PreLoad"); + AZ_Assert(RuntimeDataOverrides::IsPreloadBehaviorEnforced(m_runtimeOverrides), "RuntimeComponent::m_runtimeAsset Auto load behavior MUST be set to AZ::Data::AssetLoadBehavior::PreLoad"); } void RuntimeComponent::InitializeExecution() { #if defined(SCRIPT_CANVAS_RUNTIME_ASSET_CHECK) - if (!m_runtimeAsset.Get()) + if (!m_runtimeOverrides.m_runtimeAsset.Get()) { - AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeAsset.GetId().ToString().data()); + AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString().data()); return; } #else - AZ_Assert(m_runtimeAsset.Get(), "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeAsset.GetId().ToString().data()); + AZ_Assert(m_runtimeAsset.Get(), "RuntimeComponent::m_runtimeAsset AssetId: %s was valid, but the data was not pre-loaded, so this script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString().data()); #endif AZ_PROFILE_SCOPE_DYNAMIC(AZ::Debug::ProfileCategory::ScriptCanvas, "RuntimeComponent::InitializeExecution (%s)", m_runtimeAsset.GetId().ToString().c_str()); - SCRIPT_CANVAS_PERFORMANCE_SCOPE_INITIALIZATION(m_scriptCanvasId, m_runtimeAsset.GetId()); - m_executionState = ExecutionState::Create(ExecutionStateConfig(m_runtimeAsset, *this)); + SCRIPT_CANVAS_PERFORMANCE_SCOPE_INITIALIZATION(m_scriptCanvasId, m_runtimeOverrides.m_runtimeAsset.GetId()); + m_executionState = ExecutionState::Create(ExecutionStateConfig(m_runtimeOverrides.m_runtimeAsset, *this)); #if defined(SCRIPT_CANVAS_RUNTIME_ASSET_CHECK) if (!m_executionState) { - AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s failed to create an execution state, possibly due to missing dependent asset, script will not run", m_runtimeAsset.GetId().ToString().data()); + AZ_Error("ScriptCanvas", false, "RuntimeComponent::m_runtimeAsset AssetId: %s failed to create an execution state, possibly due to missing dependent asset, script will not run", m_runtimeOverrides.m_runtimeAsset.GetId().ToString().data()); return; } #else @@ -135,7 +133,7 @@ namespace ScriptCanvas AZ::EntityBus::Handler::BusConnect(GetEntityId()); m_executionState->Initialize(); } - + void RuntimeComponent::OnEntityActivated(const AZ::EntityId&) { Execute(); @@ -151,24 +149,18 @@ namespace ScriptCanvas if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(RuntimeComponentCpp::Version::Current, &RuntimeComponent::VersionConverter) - ->Field("m_runtimeAsset", &RuntimeComponent::m_runtimeAsset) - ->Field("m_variableOverrides", &RuntimeComponent::m_variableOverrides) + ->Version(static_cast(RuntimeComponentCpp::RuntimeComponentVersion::Current), &RuntimeComponent::VersionConverter) + ->Field("runtimeOverrides", &RuntimeComponent::m_runtimeOverrides) ; } } - void RuntimeComponent::SetVariableOverrides(const VariableData& overrideData) - { - m_variableOverrides = overrideData; - } - void RuntimeComponent::StopExecution() { if (m_executionState) { m_executionState->StopExecution(); - SCRIPT_CANVAS_PERFORMANCE_FINALIZE_TIMER(GetScriptCanvasId(), m_runtimeAsset.GetId()); + SCRIPT_CANVAS_PERFORMANCE_FINALIZE_TIMER(GetScriptCanvasId(), m_runtimeOverrides.m_runtimeAsset.GetId()); SC_EXECUTION_TRACE_GRAPH_DEACTIVATED(CreateActivationInfo()); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h index 3bee2ea592..b24cd55069 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/RuntimeComponent.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -17,9 +17,6 @@ #include #include -#include "RuntimeComponent.h" - - namespace ScriptCanvas { using VariableIdMap = AZStd::unordered_map; @@ -45,11 +42,8 @@ namespace ScriptCanvas RuntimeComponent() = default; - RuntimeComponent(AZ::Data::Asset runtimeAsset); - - const AZ::Data::Asset& GetAsset() const; - - const RuntimeData& GetAssetData() const; + // used to provide debug symbols, usually coming in the form of Node/Slot/Variable IDs + const RuntimeData& GetRuntimeAssetData() const; GraphIdentifier GetGraphIdentifier() const; @@ -57,9 +51,9 @@ namespace ScriptCanvas AZ::EntityId GetScriptCanvasId() const; - const VariableData& GetVariableOverrides() const; + const RuntimeDataOverrides& GetRuntimeDataOverrides() const; - void SetVariableOverrides(const VariableData& overrideData); + void SetRuntimeDataOverrides(const RuntimeDataOverrides& overrideData); protected: static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) @@ -94,15 +88,8 @@ namespace ScriptCanvas void StopExecution(); private: - AZ::Data::Asset m_runtimeAsset; ExecutionStatePtr m_executionState; AZ::EntityId m_scriptCanvasId; - - //! Per instance variable data overrides for the runtime asset - //! This is serialized when building this component from the EditorScriptCanvasComponent - // \todo remove the names from this data, and make it more lightweight - // it only needs variable id and value - // move the other information to the runtime system component - VariableData m_variableOverrides; + RuntimeDataOverrides m_runtimeOverrides; }; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 37a7ab898c..1851b5e65d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -1,12 +1,13 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ #include #include +#include #include #include #include @@ -41,11 +42,11 @@ namespace AbstractCodeModelCpp using namespace ScriptCanvas::Grammar; AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*> Intersection - ( const AZStd::unordered_multimap& lhs + (const AZStd::unordered_multimap& lhs , const AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*>& rhs) { AZStd::unordered_set< const Nodes::Core::FunctionDefinitionNode*> intersection; - + for (auto candidate : lhs) { if (rhs.contains(candidate.first)) @@ -147,7 +148,7 @@ namespace ScriptCanvas } } m_functions.clear(); - + m_userInsThatRequireTopology.clear(); m_userOutsThatRequireTopology.clear(); @@ -239,7 +240,7 @@ namespace ScriptCanvas // #functions2 slot<->variable consider getting all variables from the UX variable manager, or from the ACM and looking them up in the variable manager for ordering m_sourceVariableByDatum.insert(AZStd::make_pair(datum, &variablePair.second)); } - + } for (auto& sourceVariable : sortedVariables) @@ -424,7 +425,7 @@ namespace ScriptCanvas } void AbstractCodeModel::AddExecutionMapIn - ( UserInParseTopologyResult /*result*/ + (UserInParseTopologyResult /*result*/ , ExecutionTreeConstPtr root , const AZStd::vector& outCalls , AZStd::string_view defaultOutName @@ -441,10 +442,10 @@ namespace ScriptCanvas for (auto& input : functionInput) { in.inputs.push_back - ({ GetOriginalVariableName(input.second->m_source, nodelingIn) - , input.second->m_source->m_name - , input.second->m_source->m_datum - , input.second->m_source->m_sourceVariableId }); + ({ GetOriginalVariableName(input.second->m_source, nodelingIn) + , input.second->m_source->m_name + , input.second->m_source->m_datum + , input.second->m_source->m_sourceVariableId }); } if (!root->HasExplicitUserOutCalls()) @@ -473,10 +474,10 @@ namespace ScriptCanvas { const auto& returnValueVariable = root->GetReturnValue(returnValueIndex).second->m_source; out.outputs.push_back - ({ GetOriginalVariableName(returnValueVariable, *uniqueNodelingsOut.begin()) - , returnValueVariable->m_name - , returnValueVariable->m_datum.GetType() - , returnValueVariable->m_sourceVariableId }); + ({ GetOriginalVariableName(returnValueVariable, *uniqueNodelingsOut.begin()) + , returnValueVariable->m_name + , returnValueVariable->m_datum.GetType() + , returnValueVariable->m_sourceVariableId }); } in.outs.push_back(AZStd::move(out)); @@ -505,15 +506,15 @@ namespace ScriptCanvas SetDisplayAndParsedName(out, defaultOutName); out.sourceID = defaultOutId; } - + for (size_t inputIndex = 0; inputIndex < outCall->GetInputCount(); ++inputIndex) { const auto& returnValueVariable = outCall->GetInput(inputIndex).m_value; out.outputs.push_back - ({ GetOriginalVariableName(returnValueVariable, outCallID.m_node) - , returnValueVariable->m_name - , returnValueVariable->m_datum.GetType() - , returnValueVariable->m_sourceVariableId }); + ({ GetOriginalVariableName(returnValueVariable, outCallID.m_node) + , returnValueVariable->m_name + , returnValueVariable->m_datum.GetType() + , returnValueVariable->m_sourceVariableId }); } AZStd::const_pointer_cast(outCall)->SetOutCallIndex(m_outIndexCount); @@ -543,20 +544,20 @@ namespace ScriptCanvas { const auto& inputVariable = outCall->GetInput(inputIndex).m_value; out.outputs.push_back - ({ GetOriginalVariableName(inputVariable, &nodeling) - , inputVariable->m_name - , inputVariable->m_datum.GetType() - , inputVariable->m_sourceVariableId }); + ({ GetOriginalVariableName(inputVariable, &nodeling) + , inputVariable->m_name + , inputVariable->m_datum.GetType() + , inputVariable->m_sourceVariableId }); } for (size_t returnValueIndex = 0; returnValueIndex < outCall->GetReturnValueCount(); ++returnValueIndex) { const auto& returnValueVariable = outCall->GetReturnValue(returnValueIndex).second->m_source; out.outputs.push_back - ({ GetOriginalVariableName(returnValueVariable, &nodeling) - , returnValueVariable->m_name - , returnValueVariable->m_datum.GetType() - , returnValueVariable->m_sourceVariableId }); + ({ GetOriginalVariableName(returnValueVariable, &nodeling) + , returnValueVariable->m_name + , returnValueVariable->m_datum.GetType() + , returnValueVariable->m_sourceVariableId }); } AZStd::const_pointer_cast(outCall)->SetOutCallIndex(m_outIndexCount); @@ -697,7 +698,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) @@ -755,7 +756,7 @@ namespace ScriptCanvas } AZStd::vector AbstractCodeModel::CombineVariableLists - ( const AZStd::vector& constructionNodeables + (const AZStd::vector& constructionNodeables , const AZStd::vector>& constructionInputVariables , const AZStd::vector>& entityIds) const { @@ -766,12 +767,12 @@ namespace ScriptCanvas const void* nodeableAsVoidPtr = nodeable; auto iter = AZStd::find_if - ( m_nodeablesByNode.begin() + (m_nodeablesByNode.begin() , m_nodeablesByNode.end() - , [&](const auto& candidate) - { - return candidate.second->m_nodeable->m_datum.GetAsDanger() == nodeableAsVoidPtr; - }); + , [&](const auto& candidate) + { + return candidate.second->m_nodeable->m_datum.GetAsDanger() == nodeableAsVoidPtr; + }); if (iter != m_nodeablesByNode.end()) { @@ -784,7 +785,7 @@ namespace ScriptCanvas for (const auto& variable : entityIds) { - auto iter = AZStd::find_if( m_variables.begin(), m_variables.end(), [&](const auto& candidate) { + auto iter = AZStd::find_if(m_variables.begin(), m_variables.end(), [&](const auto& candidate) { if (candidate->m_datum.GetType() == Data::Type::EntityID()) { bool isVariableIdMatch = candidate->m_sourceVariableId == variable.first; @@ -836,7 +837,7 @@ namespace ScriptCanvas { ExecutionTreePtr child = AZStd::make_shared(); child->SetParent(parent); - child->SetId({node, slot}); + child->SetId({ node, slot }); child->SetScope(parent ? parent->ModScope() : m_graphScope); return child; } @@ -944,7 +945,7 @@ namespace ScriptCanvas AddError(node.GetEntityId(), nullptr, ParseErrors::EventNodeConnectCallMalformed); return false; } - + auto azEventNode = azrtti_cast(&node); if (!azEventNode) { @@ -1081,7 +1082,7 @@ namespace ScriptCanvas { // Node output is input data to a function definition OutputAssignmentPtr output = CreateOutput(execution, outputSlot, {}, "input"); - + if (auto variable = FindReferencedVariableChecked(execution, outputSlot)) { output->m_assignments.push_back(variable); @@ -1222,11 +1223,11 @@ namespace ScriptCanvas if (m_uniqueInNames.contains(displayName)) { AddError - ( nodeling->GetEntityId() + (nodeling->GetEntityId() , nullptr , AZStd::string::format - ( "%s is the name of multiple In Nodelings in a subgraph,\n" - "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data())); + ("%s is the name of multiple In Nodelings in a subgraph,\n" + "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data())); return; } else @@ -1258,8 +1259,8 @@ namespace ScriptCanvas AddError(nodeling->GetEntityId() , nullptr , AZStd::string::format - ( "%s is the name of multiple In Nodelings in a subgraph,\n" - "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data())); + ("%s is the name of multiple In Nodelings in a subgraph,\n" + "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data())); } else { @@ -1354,7 +1355,7 @@ namespace ScriptCanvas if (ExecutionContainsCycles(node, outSlot)) { AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format - ( "Execution cycle detected (see connections to %s-%s. Use a looping node like While or For" + ("Execution cycle detected (see connections to %s-%s. Use a looping node like While or For" , node.GetDebugName().data(), outSlot.GetName().data()).data())); return true; @@ -1368,12 +1369,12 @@ namespace ScriptCanvas AbstractCodeModel::ReturnValueConnections AbstractCodeModel::FindAssignments(ExecutionTreeConstPtr execution, const Slot& output) { ReturnValueConnections connections; - + if (auto variable = FindReferencedVariableChecked(execution, output)) { connections.m_returnValuesOrReferences.push_back(variable); } - + auto connectedNodes = execution->GetId().m_node->GetConnectedNodes(output); bool isAtLeastOneReturnValueFound = false; @@ -1453,8 +1454,7 @@ namespace ScriptCanvas { result.m_mostParent = outputSource; } - } - while (childSequenceIndex); + } while (childSequenceIndex); } } @@ -1477,7 +1477,7 @@ namespace ScriptCanvas return slot && candidate.second == slot; }); - return iter != scriptCanvasNodesConnectedToInput.end() ? *iter : EndpointResolved{nullptr, nullptr}; + return iter != scriptCanvasNodesConnectedToInput.end() ? *iter : EndpointResolved{ nullptr, nullptr }; }; for (size_t childIndex = 0; childIndex < outputSource->GetChildrenCount(); ++childIndex) @@ -1543,8 +1543,8 @@ namespace ScriptCanvas for (const auto& otherConnections : scriptCanvasNodesConnectedToInput) { if (otherConnections.first == outputSCNode - && otherConnections.second != outputSlot - && InSimultaneousDataPath(*outputSCNode, *otherConnections.second, *outputSlot)) + && otherConnections.second != outputSlot + && InSimultaneousDataPath(*outputSCNode, *otherConnections.second, *outputSlot)) { AddError(executionWithInput->GetId().m_node->GetEntityId(), executionWithInput, ParseErrors::MultipleSimulaneousInputValues); } @@ -1570,7 +1570,7 @@ namespace ScriptCanvas VariableConstPtr AbstractCodeModel::FindVariable(const AZ::EntityId& sourceNodeId) const { auto resultIter = AZStd::find_if - ( m_variables.begin() + (m_variables.begin() , m_variables.end() , [&sourceNodeId](const VariableConstPtr& candidate) { return candidate->m_nodeableNodeId == sourceNodeId; }); @@ -1580,7 +1580,7 @@ namespace ScriptCanvas VariableConstPtr AbstractCodeModel::FindVariable(const VariableId& sourceVariableId) const { auto resultIter = AZStd::find_if - ( m_variables.begin() + (m_variables.begin() , m_variables.end() , [&sourceVariableId](const VariableConstPtr& candidate) { return candidate->m_sourceVariableId == sourceVariableId; }); @@ -1591,7 +1591,7 @@ namespace ScriptCanvas { if (IsUserNodeable(variable)) { - auto iter = AZStd::find_if(m_nodeablesByNode.begin(), m_nodeablesByNode.end(), [&variable](auto& candidate){ return candidate.second->m_nodeable == variable; }); + auto iter = AZStd::find_if(m_nodeablesByNode.begin(), m_nodeablesByNode.end(), [&variable](auto& candidate) { return candidate.second->m_nodeable == variable; }); if (iter != m_nodeablesByNode.end()) { return iter->second->m_simpleName; @@ -1604,7 +1604,7 @@ namespace ScriptCanvas const AZStd::pair* AbstractCodeModel::FindStaticVariable(VariableConstPtr variable) const { auto iter = AZStd::find_if - ( m_staticVariableNames.begin() + (m_staticVariableNames.begin() , m_staticVariableNames.end() , [&](const auto& candidate) { return candidate.first == variable; }); @@ -1622,7 +1622,7 @@ namespace ScriptCanvas else { const_cast(this)->AddError(execution, aznew ParseError(slot.GetNodeId(), AZStd::string::format - ( "Failed to find member variable for Variable Reference in slot: %s Id: %s" + ("Failed to find member variable for Variable Reference in slot: %s Id: %s" , slot.GetName().data() , slot.GetVariableReference().ToString().data()))); } @@ -1965,7 +1965,7 @@ namespace ScriptCanvas return {}; } - + AZStd::sys_time_t AbstractCodeModel::GetParseDuration() const { return m_parseDuration; @@ -2091,7 +2091,7 @@ namespace ScriptCanvas { const AZStd::vector& slots = outcome.GetValue(); if (AZStd::find(slots.begin(), slots.end(), &reference) != slots.end() - && AZStd::find(slots.begin(), slots.end(), &candidate) != slots.end()) + && AZStd::find(slots.begin(), slots.end(), &candidate) != slots.end()) { return true; } @@ -2165,7 +2165,7 @@ namespace ScriptCanvas if (m_start) { - roots.push_back(m_start); + roots.push_back(m_start); } for (auto& nodeableParse : m_nodeablesByNode) @@ -2237,7 +2237,7 @@ namespace ScriptCanvas { ExecutionTreePtr child = CreateChild(parent, node, outSlot); child->SetScope(AZStd::make_shared()); - child->ModScope()->m_parent = parent ? parent->ModScope(): m_graphScope; + child->ModScope()->m_parent = parent ? parent->ModScope() : m_graphScope; return child; } @@ -2334,7 +2334,7 @@ namespace ScriptCanvas AddError(nullptr, ValidationConstPtr(aznew InactiveGraph())); } } - else + else { MarkParseStop(); @@ -2629,9 +2629,9 @@ namespace ScriptCanvas // create a variable declaration ExecutionTreePtr variableConstruction = CreateChild(inPreviouslyExecutedScopeResult.m_mostParent->ModParent(), nullptr, nullptr); - variableConstruction->AddInput({ nullptr , newInputResultOfAssignment, DebugDataSource::FromInternal()}); + variableConstruction->AddInput({ nullptr , newInputResultOfAssignment, DebugDataSource::FromInternal() }); variableConstruction->SetSymbol(Symbol::VariableDeclaration); - + // splice the variable declaration right before the most parent for loop is executed auto positionOutcome = mostForLoopParent->RemoveChild(inPreviouslyExecutedScopeResult.m_mostParent); if (!positionOutcome.IsSuccess()) @@ -2701,7 +2701,7 @@ namespace ScriptCanvas case VariableConstructionRequirement::InputVariable: { - auto variableID = variable->m_sourceVariableId.IsValid() ? variable->m_sourceVariableId : VariableId::MakeVariableId(); + auto variableID = variable->m_sourceVariableId.IsValid() ? variable->m_sourceVariableId : MakeParserGeneratedId(m_generatedIdCount++); inputVariableIds.push_back(variableID); inputVariablesById.insert({ variableID, variable }); // sort revealed a datum copy issue: type is not preserved, workaround below @@ -2755,7 +2755,7 @@ namespace ScriptCanvas { auto& localStatics = ModStaticVariablesNames(staticVariable->m_source); auto iter = AZStd::find_if - ( localStatics.begin() + (localStatics.begin() , localStatics.end() , [&](const auto& candidate) { return candidate.first == staticVariable; }); @@ -2834,16 +2834,16 @@ namespace ScriptCanvas { switch (execution->GetSymbol()) { - // nothing required + // nothing required case Symbol::PlaceHolderDuringParsing: break; - // out and return value information + // out and return value information case Symbol::FunctionDefinition: AddDebugInformationFunctionDefinition(execution); break; - // add in out everything + // add in out everything case Symbol::ForEach: case Symbol::FunctionCall: case Symbol::OperatorAddition: @@ -2857,7 +2857,7 @@ namespace ScriptCanvas AddDebugInformationOut(execution); break; - // add in but not out + // add in but not out case Symbol::Break: case Symbol::LogicalAND: case Symbol::LogicalNOT: @@ -2871,8 +2871,8 @@ namespace ScriptCanvas AddDebugInformationIn(execution); break; - // add in-debug-info if the if condition is NOT prefixed with logic or comparison expression (which will have the in-debug-info) - // add out-debug-info in all cases including including empty cases + // add in-debug-info if the if condition is NOT prefixed with logic or comparison expression (which will have the in-debug-info) + // add out-debug-info in all cases including including empty cases case Symbol::IfCondition: if (!(execution->GetId().m_node->IsIfBranchPrefacedWithBooleanExpression())) { @@ -2900,7 +2900,7 @@ namespace ScriptCanvas if (dependencies.userSubgraphs.find(m_source.m_namespacePath) != dependencies.userSubgraphs.end()) { AZStd::string circularDependency = AZStd::string::format - ( ParseErrors::CircularDependencyFormat + (ParseErrors::CircularDependencyFormat , m_source.m_name.data() , node.GetDebugName().data() , m_source.m_name.data()); @@ -2908,6 +2908,7 @@ namespace ScriptCanvas AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), circularDependency)); } + // #functions2 make this use an identifier for the node, for property window display and easier find/replace updates // this part must NOT recurse, the dependency tree should remain a tree and not be flattened m_orderedDependencies.source.MergeWith(dependencies); } @@ -2950,11 +2951,32 @@ namespace ScriptCanvas { if (!input->m_sourceVariableId.IsValid() && IsEntityIdThatRequiresRuntimeRemap(input)) { - input->m_sourceVariableId = VariableId::MakeVariableId(); + input->m_sourceVariableId = MakeParserGeneratedId(m_generatedIdCount++); input->m_source = nullptr; // promote to member variable for at this stage, optimizations on data flow will occur later input->m_isMember = true; - input->m_name = m_graphScope->AddVariableName(input->m_name); + + AZStd::string entityVariableName; + + if (slotAndVariable.m_slot) + { + if (execution->GetId().m_node) + { + entityVariableName.append(execution->GetId().m_node->GetNodeName()); + entityVariableName.append("."); + entityVariableName.append(slotAndVariable.m_slot->GetName()); + } + else + { + entityVariableName.append(slotAndVariable.m_slot->GetName()); + } + } + else + { + entityVariableName = input->m_name; + } + + input->m_name = m_graphScope->AddVariableName(entityVariableName); AddVariable(input); } } @@ -3020,11 +3042,11 @@ namespace ScriptCanvas CullUnusedVariables(); if (allRootsArePure - && m_ebusHandlingByNode.empty() - && m_eventHandlingByNode.empty() - && m_nodeablesByNode.empty() - && m_variableWriteHandlingByVariable.empty() - && m_subgraphInterface.IsParsedPure()) + && m_ebusHandlingByNode.empty() + && m_eventHandlingByNode.empty() + && m_nodeablesByNode.empty() + && m_variableWriteHandlingByVariable.empty() + && m_subgraphInterface.IsParsedPure()) { if (m_start) { @@ -3077,7 +3099,7 @@ namespace ScriptCanvas void AbstractCodeModel::ParseExecutionLoop(ExecutionTreePtr executionLoop) { AddDebugInfiniteLoopDetectionInLoop(executionLoop); - + auto loopSlot = executionLoop->GetId().m_node->GetSlot(executionLoop->GetId().m_node->GetLoopSlotId()); AZ_Assert(loopSlot, "Node did not return a valid loop slot"); ExecutionTreePtr executionLoopBody = OpenScope(executionLoop, executionLoop->GetId().m_node, loopSlot); @@ -3255,7 +3277,7 @@ namespace ScriptCanvas } else if (numConnections == 1) { - ParseExecutionFunctionRecurse(execution, execution->ModChild(0), outSlot, executionOutNodes[0]); + ParseExecutionFunctionRecurse(execution, execution->ModChild(0), outSlot, executionOutNodes[0]); } else { @@ -3762,7 +3784,7 @@ namespace ScriptCanvas trueValue->m_source = once; trueValue->m_datum = Datum(Data::BooleanType(true)); once->AddInput({ nullptr, trueValue, DebugDataSource::FromInternal() }); - + ExecutionTreePtr onReset = CreateChild(once, once->GetId().m_node, onceResetSlot); onReset->SetSymbol(Symbol::PlaceHolderDuringParsing); onReset->MarkInputOutputPreprocessed(); @@ -3849,7 +3871,7 @@ namespace ScriptCanvas executionSwitch->SetSymbol(Symbol::Switch); ParseExecutionSequentialChildren(executionSwitch); } - + // the execution will already have its function definition defined, this will create the body of that function void AbstractCodeModel::ParseExecutionTreeBody(ExecutionTreePtr execution, const Slot& outSlot) { @@ -4112,7 +4134,7 @@ namespace ScriptCanvas { auto& userFunctionNode = *userFunctionIter->first; auto outSlots = userFunctionNode.GetSlotsByType(CombinedSlotType::ExecutionOut); - + if (outSlots.empty() || !outSlots.front()) { AddError(userFunctionNode.GetEntityId(), nullptr, ScriptCanvas::ParseErrors::NoOutSlotInFunctionDefinitionStart); @@ -4179,7 +4201,7 @@ namespace ScriptCanvas auto onceControl = AddMemberVariable(Datum(Data::BooleanType(true)), "onceControl"); m_controlVariablesBySourceNode.insert({ &node, onceControl }); } - else + else { const auto nodelingType = CheckNodelingType(node); if (nodelingType != NodelingType::None) @@ -4208,7 +4230,7 @@ namespace ScriptCanvas { const VariableId assignedFromId = execution->GetId().m_node->GetVariableIdRead(execution->GetId().m_slot); auto variableRead = assignedFromId.IsValid() ? FindVariable(assignedFromId) : nullptr; - + if (variableRead) { // nullptr is acceptable here @@ -4314,7 +4336,7 @@ namespace ScriptCanvas for (auto sourceNodeAndSlot : nodes) { AddError(nullptr, aznew ScopedDataConnectionEvent - ( execution->GetNodeId() + (execution->GetNodeId() , targetNode , targetSlot , *sourceNodeAndSlot.first @@ -4324,7 +4346,7 @@ namespace ScriptCanvas } } } - + bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution) { auto node = execution->GetId().m_node; @@ -4364,7 +4386,7 @@ namespace ScriptCanvas { auto node2 = execution->GetId().m_node; AddError(execution, aznew ParseError(node2->GetEntityId(), AZStd::string::format - ( "Failed to find member variable for Node: %s Id: %s" + ("Failed to find member variable for Node: %s Id: %s" , node2->GetNodeName().data() , node2->GetEntityId().ToString().data()).data())); } @@ -4394,7 +4416,7 @@ namespace ScriptCanvas { auto node2 = execution->GetId().m_node; AddError(execution, aznew ParseError(node2->GetEntityId(), AZStd::string::format - ( "Failed to find member variable for Node: %s Id: %s" + ("Failed to find member variable for Node: %s Id: %s" , node2->GetNodeName().data() , node2->GetEntityId().ToString().data()).data())); } @@ -4451,10 +4473,10 @@ namespace ScriptCanvas } ExecutionChild* executionChildInParent = &parent->ModChild(indexInParentCall); - + const size_t executionInputCount = execution->GetInputCount(); const size_t thisInputOffset = execution->InputHasThisPointer() ? 1 : 0; - + // the original index has ALL the input from the slots on the node // create multiple calls with separate function call nodes, but ONLY take the inputs required // as indicated by the function call info @@ -4811,7 +4833,7 @@ namespace ScriptCanvas } } } - + void AbstractCodeModel::ParseReturnValue(ExecutionTreePtr execution, const Slot& returnValueSlot) { if (auto variable = FindReferencedVariableChecked(execution, returnValueSlot)) @@ -4862,9 +4884,9 @@ namespace ScriptCanvas { ParseUserIn(iter.second, iter.first); } - + m_userInsThatRequireTopology.clear(); - + ParseUserOuts(); auto parseOutcome = m_subgraphInterface.Parse(); @@ -4920,7 +4942,7 @@ namespace ScriptCanvas AddError(root, aznew Internal::ParseError(AZ::EntityId(), "In Nodeling didn't parse properly, there were still leaves without nodelings in the execution tree.")); return; } - } + } auto& outCallsChecked = listenerCheck.GetOutCalls(); if (!result.addSingleOutToMap && outCallsChecked.empty()) @@ -4968,8 +4990,8 @@ namespace ScriptCanvas } if ((!root->HasExplicitUserOutCalls()) - && root->GetReturnValueCount() > 0 - && branches > 1) + && root->GetReturnValueCount() > 0 + && branches > 1) { AddError(root->GetNodeId(), root, ScriptCanvas::ParseErrors::TooManyBranchesForReturn); return; @@ -5005,7 +5027,7 @@ namespace ScriptCanvas AZStd::pair returnValue = execution->GetReturnValue(execution->GetReturnValueCount() - 1); AZStd::const_pointer_cast(returnValue.second)->m_isNewValue = true; } - } + } } } @@ -5029,7 +5051,7 @@ namespace ScriptCanvas result.addExplicitOutCalls = nodelingsOutCount > 1; result.isSimpleFunction = !result.addExplicitOutCalls; } - else + else { // user explicitly defined at least 1 Out and there are execution leaves without Outs, so we provide an Out to any missing ones result.addSingleOutToMap = true; @@ -5037,7 +5059,7 @@ namespace ScriptCanvas result.addExplicitOutCalls = true; result.isSimpleFunction = false; } - + return result; } @@ -5058,41 +5080,41 @@ namespace ScriptCanvas void AbstractCodeModel::ParseUserLatentData(ExecutionTreePtr execution) { - if (execution->IsOnLatentPath()) - { - if (execution->GetChildrenCount() == 0) - { - execution->AddChild({ nullptr, {}, nullptr }); - } - - auto& executionChild = execution->ModChild(0); - - // inputs are return values expected from the latent out call - for (auto& returnValue : FindUserLatentReturnValues(execution)) - { - // if there are return values, we can continue execution after - // the nodeling out that is in the path (disable the contract) - // and we must make sure there's ONLY ONE - // and no immediate ins - auto outputAssignment = CreateOutputAssignment(returnValue); - executionChild.m_output.push_back({ nullptr, outputAssignment }); - } - - auto methodRoot = execution->ModRoot(); - - // outputs are inputs to the latent out call - for (auto& inputValue : FindUserLatentOutput(execution)) - { - inputValue->m_source = methodRoot; - execution->AddInput({ nullptr, inputValue, DebugDataSource::FromVariable(SlotId{}, inputValue->m_datum.GetType(), inputValue->m_sourceVariableId) }); - } - - methodRoot->CopyInput(execution, ExecutionTree::RemapVariableSource::No); - } - else - { - AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), "immediate execution parsed data in latent thread")); - } + if (execution->IsOnLatentPath()) + { + if (execution->GetChildrenCount() == 0) + { + execution->AddChild({ nullptr, {}, nullptr }); + } + + auto& executionChild = execution->ModChild(0); + + // inputs are return values expected from the latent out call + for (auto& returnValue : FindUserLatentReturnValues(execution)) + { + // if there are return values, we can continue execution after + // the nodeling out that is in the path (disable the contract) + // and we must make sure there's ONLY ONE + // and no immediate ins + auto outputAssignment = CreateOutputAssignment(returnValue); + executionChild.m_output.push_back({ nullptr, outputAssignment }); + } + + auto methodRoot = execution->ModRoot(); + + // outputs are inputs to the latent out call + for (auto& inputValue : FindUserLatentOutput(execution)) + { + inputValue->m_source = methodRoot; + execution->AddInput({ nullptr, inputValue, DebugDataSource::FromVariable(SlotId{}, inputValue->m_datum.GetType(), inputValue->m_sourceVariableId) }); + } + + methodRoot->CopyInput(execution, ExecutionTree::RemapVariableSource::No); + } + else + { + AddError(execution, aznew Internal::ParseError(execution->GetNodeId(), "immediate execution parsed data in latent thread")); + } } void AbstractCodeModel::ParseUserOutCall(ExecutionTreePtr execution) @@ -5164,7 +5186,7 @@ namespace ScriptCanvas if (!IsConnectedToUserIn(nodeling)) { const auto report = AZStd::string::format - ( "Nodeling Out (%s) not connected to Nodeling In, functionality cannot be executed", nodeling->GetDisplayName().data()); + ("Nodeling Out (%s) not connected to Nodeling In, functionality cannot be executed", nodeling->GetDisplayName().data()); AddError(nullptr, aznew Internal::ParseError(nodeling->GetEntityId(), report)); } @@ -5172,7 +5194,7 @@ namespace ScriptCanvas else { const auto report = AZStd::string::format - ("null nodeling in immediate out list"); + ("null nodeling in immediate out list"); AddError(nullptr, aznew Internal::ParseError(nodeling->GetEntityId(), report)); } @@ -5220,7 +5242,7 @@ namespace ScriptCanvas { auto& localStatics = ModStaticVariablesNames(execution); auto iter = AZStd::find_if - (localStatics.begin() + (localStatics.begin() , localStatics.end() , [&](const auto& candidate) { return candidate.first == variable; }); @@ -5285,7 +5307,7 @@ namespace ScriptCanvas RemoveFromTree(noOpChild); } } - + void AbstractCodeModel::RemoveFromTree(ExecutionTreePtr execution) { if (!execution->GetParent()) @@ -5304,7 +5326,7 @@ namespace ScriptCanvas { AddError(execution->GetNodeId(), execution, ScriptCanvas::ParseErrors::RequiredOutputRemoved); } - + if (childCount != 0) { if (childCount > 1) @@ -5332,7 +5354,7 @@ namespace ScriptCanvas execution->Clear(); } - + AZ::Outcome> AbstractCodeModel::RemoveChild(const ExecutionTreePtr& execution, const ExecutionTreeConstPtr& child) { return execution->RemoveChild(child); @@ -5342,7 +5364,5 @@ namespace ScriptCanvas { return type == Data::eType::BehaviorContextObject; } - } - } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index c0ef720fbe..f87913d47a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -71,7 +71,7 @@ namespace ScriptCanvas AZStd::optional> CheckUserNodeableDependencyConstructionIndex(VariableConstPtr nodeable) const; AZStd::vector CombineVariableLists - ( const AZStd::vector& constructionNodeables + (const AZStd::vector& constructionNodeables , const AZStd::vector>& constructionInputVariableIds , const AZStd::vector>& entityIds) const; @@ -120,7 +120,7 @@ namespace ScriptCanvas const ParsedRuntimeInputs& GetRuntimeInputs() const; const Source& GetSource() const; - + const AZStd::string& GetSourceString() const; ExecutionTreeConstPtr GetStart() const; @@ -150,21 +150,19 @@ namespace ScriptCanvas bool IsUserNodeable(VariableConstPtr variable) const; - bool HasUserNodeableDependenciesInVariables() const; - template AZStd::vector ToVariableList(const AZStd::vector>& source) const; private: - ////////////////////////////////////////////////////////////////////////// - // Internal parsing - ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// + // Internal parsing + ////////////////////////////////////////////////////////////////////////// struct ReturnValueConnections { bool m_hasOtherConnections = false; AZStd::vector m_returnValuesOrReferences; }; - + void AddAllVariablesPreParse(); void AddAllVariablesPreParse_LegacyFunctions(); @@ -210,7 +208,7 @@ namespace ScriptCanvas bool CheckCreateRoot(const Node& node); AZStd::string CheckUniqueInterfaceNames - ( AZStd::string_view candidate + (AZStd::string_view candidate , AZStd::string_view defaultName , AZStd::unordered_set& uniqueNames , const AZStd::unordered_set& nodelingsOut); @@ -340,7 +338,7 @@ namespace ScriptCanvas void ParseExecutionLogicalExpression(ExecutionTreePtr execution, Symbol symbol); void ParseExecutionLoop(ExecutionTreePtr execution); - + void ParseExecutionMultipleOutSyntaxSugar(ExecutionTreePtr execution, const EndpointsResolved& executionOutNodes, const AZStd::vector& outSlots); void ParseExecutionMultipleOutSyntaxSugarOfSequencNode(ExecutionTreePtr sequence); @@ -428,7 +426,7 @@ namespace ScriptCanvas void PruneNoOpChildren(const ExecutionTreePtr& execution); AZ::Outcome> RemoveChild(const ExecutionTreePtr& execution, const ExecutionTreeConstPtr& child); - + void RemoveFromTree(ExecutionTreePtr execution); struct ConnectionInPreviouslyExecutedScope @@ -473,7 +471,7 @@ namespace ScriptCanvas } void AddExecutionMapIn - ( UserInParseTopologyResult result + (UserInParseTopologyResult result , ExecutionTreeConstPtr root , const AZStd::vector& outCalls , AZStd::string_view defaultOutName @@ -505,6 +503,7 @@ namespace ScriptCanvas static UserInParseTopologyResult ParseUserInTolopology(size_t nodelingsOutCount, size_t leavesWithoutNodelingsCount); size_t m_outIndexCount = 0; + size_t m_generatedIdCount = 0; ExecutionTreePtr m_start; AZStd::vector m_startNodes; ScopePtr m_graphScope; @@ -513,7 +512,7 @@ namespace ScriptCanvas AZStd::unordered_set m_userNodeables; AZStd::unordered_map m_dependencyByVariable; - + AZStd::vector m_variables; AZStd::vector m_possibleExecutionRoots; @@ -621,7 +620,7 @@ namespace ScriptCanvas for (const auto& variable : source) { auto iter = AZStd::find_if - ( m_variables.begin() + (m_variables.begin() , m_variables.end() , [&](const auto& candidate) { return candidate->m_sourceVariableId == variable.first; }); @@ -633,7 +632,5 @@ namespace ScriptCanvas return variables; } - - } - -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp index 43d0823b25..2a3801ba26 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -47,6 +47,10 @@ namespace ParsingUtilitiesCpp using namespace ScriptCanvas; using namespace ScriptCanvas::Grammar; + const AZ::u64 k_parserGeneratedMask = 0x7FC0616C94E7465F; + const size_t k_maskIndex = 0; + const size_t k_countIndex = 1; + class PrettyPrinter : public ExecutionTreeTraversalListener { @@ -85,7 +89,7 @@ namespace ParsingUtilitiesCpp { m_result += AZStd::string::format(" # children: %zu", childCount); } - + if (m_marker == execution) { m_result += " <<<< MARKER <<<< "; @@ -97,7 +101,7 @@ namespace ParsingUtilitiesCpp m_result += "\n"; } - void EvaluateRoot(ExecutionTreeConstPtr node, const Slot* ) + void EvaluateRoot(ExecutionTreeConstPtr node, const Slot*) { m_result += "\nRoot:\n"; } @@ -356,7 +360,7 @@ namespace ScriptCanvas else if (nodeling->IsExecutionExit()) { return NodelingType::Out; - } + } } return NodelingType::None; @@ -785,7 +789,7 @@ namespace ScriptCanvas { return execution->GetInputCount() > index && ((execution->GetInput(index).m_value->m_datum.GetAs() && *execution->GetInput(index).m_value->m_datum.GetAs() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction) - || (execution->GetInput(index).m_value->m_datum.GetAs() && *execution->GetInput(index).m_value->m_datum.GetAs() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction)); + || (execution->GetInput(index).m_value->m_datum.GetAs() && *execution->GetInput(index).m_value->m_datum.GetAs() == GraphOwnerId && !execution->GetInput(index).m_value->m_isExposedToConstruction)); } bool IsIsNull(const ExecutionTreeConstPtr& execution) @@ -855,7 +859,7 @@ namespace ScriptCanvas return true; } } - + return IsMidSequence(parent); } @@ -1001,10 +1005,16 @@ namespace ScriptCanvas return true; } + bool IsParserGeneratedId(const ScriptCanvas::VariableId& id) + { + using namespace ParsingUtilitiesCpp; + return reinterpret_cast(id.m_id.data)[k_maskIndex] == k_parserGeneratedMask; + } + bool IsPropertyExtractionSlot(const ExecutionTreeConstPtr& execution, const Slot* outputSlot) { auto iter = AZStd::find_if - ( execution->GetPropertyExtractionSources().begin() + (execution->GetPropertyExtractionSources().begin() , execution->GetPropertyExtractionSources().end() , [&](const auto& iter) { return iter.first == outputSlot; }); @@ -1052,9 +1062,9 @@ namespace ScriptCanvas bool IsSequenceNode(const ExecutionTreeConstPtr& execution) { return (IsSequenceNode(execution->GetId().m_node) - && execution->GetId().m_slot->GetType() == CombinedSlotType::ExecutionIn); + && execution->GetId().m_slot->GetType() == CombinedSlotType::ExecutionIn); } - + bool IsSwitchStatement(const ExecutionTreeConstPtr& execution) { return execution->GetId().m_node->IsSwitchStatement() @@ -1120,6 +1130,16 @@ namespace ScriptCanvas return AZStd::string::format("%s%s", k_memberNamePrefix, name.data()); } + VariableId MakeParserGeneratedId(size_t count) + { + using namespace ParsingUtilitiesCpp; + + AZ::Uuid parserGenerated; + reinterpret_cast(parserGenerated.data)[k_maskIndex] = k_parserGeneratedMask; + reinterpret_cast(parserGenerated.data)[k_countIndex] = count; + return ScriptCanvas::VariableId(parserGenerated); + } + VariableConstructionRequirement ParseConstructionRequirement(VariableConstPtr variable) { if (IsEntityIdThatRequiresRuntimeRemap(variable)) @@ -1216,7 +1236,7 @@ namespace ScriptCanvas result += AZStd::string::format("Variable: %s, Type: %s, Scope: %s, \n" , variable->m_name.data() , Data::GetName(variable->m_datum.GetType()).data() - , variable->m_isMember ? "Member" : "Local" ); + , variable->m_isMember ? "Member" : "Local"); } auto roots = model.GetAllExecutionRoots(); @@ -1261,11 +1281,11 @@ namespace ScriptCanvas bool RequiresRuntimeRemap(const AZ::EntityId& entityId) { - return entityId.IsValid() + return entityId.IsValid() && entityId != UniqueId && entityId != GraphOwnerId; } - + AZStd::string SlotNameToIndexString(const Slot& slot) { auto indexString = slot.GetName(); @@ -1445,5 +1465,5 @@ namespace ScriptCanvas } } } - } -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h index d264983e03..a1c6ac0e44 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/ParsingUtilities.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -113,7 +113,7 @@ namespace ScriptCanvas bool IsInfiniteSelfEntityActivationLoop(const AbstractCodeModel& model, ExecutionTreeConstPtr execution); bool IsInfiniteSelfEntityActivationLoopRecurse(const AbstractCodeModel& model, ExecutionTreeConstPtr execution); - + bool IsInfiniteVariableWriteHandlingLoop(const AbstractCodeModel& model, VariableWriteHandlingPtr variableHandling, ExecutionTreeConstPtr execution, bool isConnected); bool IsInLoop(const ExecutionTreeConstPtr& execution); @@ -144,6 +144,8 @@ namespace ScriptCanvas bool IsOnSelfEntityActivated(const AbstractCodeModel& model, ExecutionTreeConstPtr execution); + bool IsParserGeneratedId(const VariableId& id); + bool IsPropertyExtractionSlot(const ExecutionTreeConstPtr& execution, const Slot* outputSlot); bool IsPropertyExtractionNode(const ExecutionTreeConstPtr& execution); @@ -178,6 +180,8 @@ namespace ScriptCanvas bool IsWrittenMathExpression(const ExecutionTreeConstPtr& execution); + VariableId MakeParserGeneratedId(size_t count); + AZStd::string MakeMemberVariableName(AZStd::string_view name); VariableConstructionRequirement ParseConstructionRequirement(Grammar::VariableConstPtr value); @@ -203,6 +207,5 @@ namespace ScriptCanvas void TraverseTree(const AbstractCodeModel& execution, ExecutionTreeTraversalListener& listener); void TraverseTree(const ExecutionTreeConstPtr& execution, ExecutionTreeTraversalListener& listener); - } - -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp index 82d93ac45e..b1e58cac54 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -99,9 +99,9 @@ namespace ScriptCanvas m_inputs.clear(); m_outputs.clear(); } - + bool FunctionPrototype::IsVoid() const - { + { return m_outputs.empty(); } @@ -200,24 +200,23 @@ namespace ScriptCanvas baseName.append(suffix); return AddVariableName(baseName); } - + AZ::s32 Scope::AddNameCount(AZStd::string_view name) { AZ::s32 count = -1; ScopePtr ns = shared_from_this(); - + do { auto iter = ns->m_baseNameToCount.find(name); - + if (iter != ns->m_baseNameToCount.end()) { // a basename has been found in current or parent scope, get the latest count count = iter->second; break; } - } - while ((ns = AZStd::const_pointer_cast(ns->m_parent))); + } while ((ns = AZStd::const_pointer_cast(ns->m_parent))); auto iter = m_baseNameToCount.find(name); if (iter == m_baseNameToCount.end()) @@ -235,7 +234,7 @@ namespace ScriptCanvas const VariableData Source::k_emptyVardata{}; Source::Source - ( const Graph& graph + (const Graph& graph , const AZ::Data::AssetId& id , const GraphData& graphData , const VariableData& variableData @@ -277,8 +276,8 @@ namespace ScriptCanvas AzFramework::StringFunc::Path::StripExtension(namespacePath); return AZ::Success(Source - ( *request.graph - , request.assetId + (*request.graph + , request.scriptAssetId , *graphData , *sourceVariableData , name @@ -294,23 +293,23 @@ namespace ScriptCanvas } Variable::Variable(Datum&& datum) - : m_datum(datum) + : m_datum(datum) {} - + Variable::Variable(const Datum& datum, const AZStd::string& name, TraitsFlags traitsFlags) : m_datum(datum) , m_name(name) - , m_isConst(traitsFlags & TraitsFlags::Const) - , m_isMember(traitsFlags & TraitsFlags::Member) + , m_isConst(traitsFlags& TraitsFlags::Const) + , m_isMember(traitsFlags& TraitsFlags::Member) {} Variable::Variable(Datum&& datum, AZStd::string&& name, TraitsFlags&& traitsFlags) : m_datum(datum) , m_name(name) - , m_isConst(traitsFlags & TraitsFlags::Const) - , m_isMember(traitsFlags & TraitsFlags::Member) + , m_isConst(traitsFlags& TraitsFlags::Const) + , m_isMember(traitsFlags& TraitsFlags::Member) {} - + void Variable::Reflect(AZ::ReflectContext* reflectContext) { if (auto serializeContext = azrtti_cast(reflectContext)) @@ -339,5 +338,5 @@ namespace ScriptCanvas m_variable = nullptr; m_connectionVariable = nullptr; } - } -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp index 9a164cd339..d57aa9d621 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -12,7 +12,9 @@ namespace ScriptCanvas namespace Grammar { AZ_CVAR(bool, g_disableParseOnGraphValidation, false, {}, AZ::ConsoleFunctorFlags::Null, "In case parsing the graph is interfering with opening a graph, disable parsing on validation"); - AZ_CVAR(bool, g_printAbstractCodeModel, false, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing for debug purposes."); - AZ_CVAR(bool, g_saveRawTranslationOuputToFile, false, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation for debug purposes."); + AZ_CVAR(bool, g_printAbstractCodeModel, true, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing for debug purposes."); + AZ_CVAR(bool, g_printAbstractCodeModelAtPrefabTime, false, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing (at prefab time) for debug purposes."); + AZ_CVAR(bool, g_saveRawTranslationOuputToFile, true, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation for debug purposes."); + AZ_CVAR(bool, g_saveRawTranslationOuputToFileAtPrefabTime, false, {}, AZ::ConsoleFunctorFlags::Null, "Save out the raw result of translation (at prefab time) for debug purposes."); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h index 95c57b3211..0923f32771 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -108,7 +108,7 @@ namespace ScriptCanvas constexpr const char* k_InitializeExecutionOutByRequiredCountName = "InitializeExecutionOutByRequiredCount"; constexpr const char* k_InterpretedConfigurationPerformance = "SCRIPT_CANVAS_GLOBAL_PERFORMANCE"; constexpr const char* k_InterpretedConfigurationRelease = "SCRIPT_CANVAS_GLOBAL_RELEASE"; - + constexpr const char* k_NodeableCallInterpretedOut = "ExecutionOut"; constexpr const char* k_NodeableUserBaseClassName = "Nodeable"; constexpr const char* k_NodeableSetExecutionOutName = "SetExecutionOut"; @@ -120,7 +120,7 @@ namespace ScriptCanvas constexpr const char* k_OnGraphStartFunctionName = "OnGraphStart"; constexpr const char* k_OverrideNodeableMetatableName = "OverrideNodeableMetatable"; - + constexpr const char* k_stringFormatLexicalScopeName = "string"; constexpr const char* k_stringFormatName = "format"; @@ -139,7 +139,7 @@ namespace ScriptCanvas constexpr const char* k_DependentAssetsIndexArgName = "dependentAssetsIndex"; constexpr const char* k_UnpackDependencyConstructionArgsFunctionName = "UnpackDependencyConstructionArgs"; constexpr const char* k_UnpackDependencyConstructionArgsLeafFunctionName = "UnpackDependencyConstructionArgsLeaf"; - + enum class ExecutionCharacteristics : AZ::u32 { Object, @@ -147,7 +147,7 @@ namespace ScriptCanvas }; // default to a pure, interpreted function - enum ExecutionStateSelection : AZ::u32 + enum class ExecutionStateSelection : AZ::u32 { InterpretedPure, InterpretedPureOnGraphStart, @@ -172,7 +172,7 @@ namespace ScriptCanvas Count, }; #undef REGISTER_ENUM - + // create the Symbol strings #define REGISTER_ENUM(x) #x, static const char* g_SymbolNames[] = @@ -247,7 +247,9 @@ namespace ScriptCanvas AZ_CVAR_EXTERNED(bool, g_disableParseOnGraphValidation); AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModel); + AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModelAtPrefabTime); AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFile); + AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFileAtPrefabTime); struct DependencyInfo { @@ -258,7 +260,7 @@ namespace ScriptCanvas struct Request { - AZ::Data::AssetId assetId; + AZ::Data::AssetId scriptAssetId; const Graph* graph = nullptr; AZStd::string_view name; AZStd::string_view path; @@ -291,7 +293,7 @@ namespace ScriptCanvas Source() = default; Source - ( const Graph& graph + (const Graph& graph , const AZ::Data::AssetId& id , const GraphData& graphData , const VariableData& variableData @@ -305,8 +307,8 @@ namespace ScriptCanvas AZStd::string ToTypeSafeEBusResultName(const Data::Type& type); AZStd::string ToSafeName(const AZStd::string& name); NamespacePath ToNamespacePath(AZStd::string_view path, AZStd::string_view name); - } -} + } +} namespace AZStd { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp new file mode 100644 index 0000000000..207acafd82 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include "ScriptUserDataSerializer.h" + +#include +#include + +using namespace ScriptCanvas; + +namespace AZ +{ + AZ_CLASS_ALLOCATOR_IMPL(ScriptUserDataSerializer, SystemAllocator, 0); + + JsonSerializationResult::Result ScriptUserDataSerializer::Load + ( void* outputValue + , [[maybe_unused]] const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(outputValueTypeId == azrtti_typeid(), "ScriptUserDataSerializer Load against output typeID that was not RuntimeVariable"); + AZ_Assert(outputValue, "ScriptUserDataSerializer Load against null output"); + + auto outputVariable = reinterpret_cast(outputValue); + JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); + AZ::Uuid typeId = AZ::Uuid::CreateNull(); + + auto typeIdMember = inputValue.FindMember("$type"); + if (typeIdMember == inputValue.MemberEnd()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the $type member"); + } + + result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); + if (typeId.IsNull()) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the AZ TypeId of the value"); + } + + outputVariable->value = context.GetSerializeContext()->CreateAny(typeId); + if (outputVariable->value.empty() || outputVariable->value.type() != typeId) + { + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); + } + + result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context)); + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ScriptUserDataSerializer Store finished loading RuntimeVariable" + : "ScriptUserDataSerializer Store failed to load RuntimeVariable"); + } + + JsonSerializationResult::Result ScriptUserDataSerializer::Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , [[maybe_unused]] const Uuid& valueTypeId + , JsonSerializerContext& context) + { + namespace JSR = JsonSerializationResult; + + AZ_Assert(valueTypeId == azrtti_typeid(), "RuntimeVariable Store against value typeID that was not RuntimeVariable"); + AZ_Assert(inputValue, "RuntimeVariable Store against null inputValue pointer "); + + auto inputScriptDataPtr = reinterpret_cast(inputValue); + auto defaultScriptDataPtr = reinterpret_cast(defaultValue); + auto inputAnyPtr = &inputScriptDataPtr->value; + auto defaultAnyPtr = defaultScriptDataPtr ? &defaultScriptDataPtr->value : nullptr; + + if (defaultAnyPtr) + { + ScriptCanvas::Datum inputDatum(ScriptCanvas::Data::FromAZType(inputAnyPtr->type()), ScriptCanvas::Datum::eOriginality::Copy, AZStd::any_cast(inputAnyPtr), inputAnyPtr->type()); + ScriptCanvas::Datum defaultDatum(ScriptCanvas::Data::FromAZType(defaultAnyPtr->type()), ScriptCanvas::Datum::eOriginality::Copy, AZStd::any_cast(defaultAnyPtr), defaultAnyPtr->type()); + + if (inputDatum == defaultDatum) + { + return context.Report(JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "ScriptUserDataSerializer Store used defaults for RuntimeVariable"); + } + } + + JSR::ResultCode result(JSR::Tasks::WriteValue); + outputValue.SetObject(); + + { + auto azTypeString = inputAnyPtr->type().ToString(); + rapidjson::Value typeValue; + typeValue.SetString(azTypeString.begin(), azTypeString.length(), context.GetJsonAllocator()); + result.Combine(StoreTypeId(typeValue, inputAnyPtr->type(), context)); + outputValue.AddMember("$type", typeValue, context.GetJsonAllocator()); + } + + result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context)); + + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted + ? "ScriptUserDataSerializer Store finished saving RuntimeVariable" + : "ScriptUserDataSerializer Store failed to save RuntimeVariable"); + } + +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h new file mode 100644 index 0000000000..781a3b74fe --- /dev/null +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include + +namespace AZ +{ + class ScriptUserDataSerializer + : public BaseJsonSerializer + { + public: + AZ_RTTI(ScriptUserDataSerializer, "{7E5FC193-8CDB-4251-A68B-F337027381DF}", BaseJsonSerializer); + AZ_CLASS_ALLOCATOR_DECL; + + private: + JsonSerializationResult::Result Load + ( void* outputValue + , const Uuid& outputValueTypeId + , const rapidjson::Value& inputValue + , JsonDeserializerContext& context) override; + + JsonSerializationResult::Result Store + ( rapidjson::Value& outputValue + , const void* inputValue + , const void* defaultValue + , const Uuid& valueTypeId, JsonSerializerContext& context) override; + }; +} \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToX.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToX.cpp index f95ed75be8..ade98042a0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToX.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/GraphToX.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -75,7 +75,7 @@ namespace ScriptCanvas { return m_model.GetSource().m_name; } - + AZStd::string_view GraphToX::GetFullPath() const { return m_model.GetSource().m_path; @@ -120,7 +120,7 @@ namespace ScriptCanvas resolution += Grammar::ToIdentifier(namespaces[index]); } } - + return resolution; } @@ -128,13 +128,13 @@ namespace ScriptCanvas { writer.Write(m_configuration.m_singleLineComment); } - + void GraphToX::OpenBlockComment(Writer& writer) { writer.WriteIndent(); writer.WriteLine(m_configuration.m_blockCommentOpen); } - + void GraphToX::OpenFunctionBlock(Writer& writer) { writer.WriteLineIndented(m_configuration.m_functionBlockOpen); @@ -162,7 +162,7 @@ namespace ScriptCanvas void GraphToX::WriteCopyright(Writer& writer) { OpenBlockComment(writer); - writer.WriteLine(GetAmazonCopyright()); + writer.WriteLine(GetCopyright()); CloseBlockComment(writer); } @@ -206,5 +206,5 @@ namespace ScriptCanvas writer.Write("Last written: "); writer.WriteLine(buffer); } - } -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp index 96cf4c4ce0..b44e438ba0 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -30,7 +30,6 @@ namespace TranslationCPP AZ::Outcome, AZStd::pair> ToCPlusPlus(const Grammar::AbstractCodeModel& model, bool rawSave = false) { AZStd::string dotH, dotCPP; - auto outcome = GraphToCPlusPlus::Translate(model, dotH, dotCPP); if (outcome.IsSuccess()) { @@ -48,13 +47,11 @@ namespace TranslationCPP { saveOutcome = SaveDotCPP(model.GetSource(), dotCPP); } - if (!saveOutcome.IsSuccess()) { AZ_TracePrintf("Save failed %s", saveOutcome.GetError().data()); } } - return AZ::Success(AZStd::make_pair(AZStd::move(dotH), AZStd::move(dotCPP))); } else @@ -96,16 +93,28 @@ namespace ScriptCanvas { namespace Translation { - Result ParseGraph(const Grammar::Request& request) + AZ::Outcome ParseGraph(const Grammar::Request& request) { AZ::Outcome sourceOutcome = Grammar::Source::Construct(request); if (!sourceOutcome.IsSuccess()) { - return Result(sourceOutcome.TakeError()); + return AZ::Failure(sourceOutcome.TakeError()); } - + Grammar::AbstractCodeModelConstPtr model = Grammar::AbstractCodeModel::Parse(sourceOutcome.TakeValue()); + return AZ::Success(model); + } + + Result ParseAndTranslateGraph(const Grammar::Request& request) + { + auto parseOutcome = ParseGraph(request); + if (!parseOutcome.IsSuccess()) + { + return Result(parseOutcome.TakeError()); + } + + Grammar::AbstractCodeModelConstPtr model = parseOutcome.TakeValue(); Translations translations; Errors errors; @@ -124,61 +133,52 @@ namespace ScriptCanvas } } -// if (targetFlags & (TargetFlags::Cpp | TargetFlags::Hpp)) -// { -// auto outcomeCPP = TranslationCPP::ToCPlusPlus(*model.get(), rawSave); -// if (outcomeCPP.IsSuccess()) -// { -// auto hppAndCpp = outcomeCPP.TakeValue(); -// -// TargetResult cppResult; -// cppResult.m_text = AZStd::move(hppAndCpp.first); -// translations.emplace(TargetFlags::Hpp, AZStd::move(cppResult)); -// TargetResult hppResult; -// hppResult.m_text = AZStd::move(hppAndCpp.second); -// translations.emplace(TargetFlags::Cpp, AZStd::move(hppResult)); -// } -// else -// { -// auto hppAndCpp = outcomeCPP.TakeError(); -// errors.emplace(TargetFlags::Hpp, AZStd::move(hppAndCpp.first)); -// errors.emplace(TargetFlags::Cpp, AZStd::move(hppAndCpp.second)); -// } -// } + // if (targetFlags & (TargetFlags::Cpp | TargetFlags::Hpp)) + // { + // auto outcomeCPP = TranslationCPP::ToCPlusPlus(*model.get(), rawSave); + // if (outcomeCPP.IsSuccess()) + // { + // auto hppAndCpp = outcomeCPP.TakeValue(); + // + // TargetResult cppResult; + // cppResult.m_text = AZStd::move(hppAndCpp.first); + // translations.emplace(TargetFlags::Hpp, AZStd::move(cppResult)); + // TargetResult hppResult; + // hppResult.m_text = AZStd::move(hppAndCpp.second); + // translations.emplace(TargetFlags::Cpp, AZStd::move(hppResult)); + // } + // else + // { + // auto hppAndCpp = outcomeCPP.TakeError(); + // errors.emplace(TargetFlags::Hpp, AZStd::move(hppAndCpp.first)); + // errors.emplace(TargetFlags::Cpp, AZStd::move(hppAndCpp.second)); + // } + // } } - else - { - ValidationResults results; - for (auto& test : model->GetValidationEvents()) - { - results.AddValidationEvent(test.get()); - } - } return Result(model, AZStd::move(translations), AZStd::move(errors)); - } + } Result ToCPlusPlusAndLua(const Grammar::Request& request) { Grammar::Request toBoth = request; toBoth.translationTargetFlags = TargetFlags::Lua | TargetFlags::Cpp; - return ParseGraph(toBoth); + return ParseAndTranslateGraph(toBoth); } Result ToCPlusPlus(const Grammar::Request& request) { Grammar::Request toCpp = request; toCpp.translationTargetFlags = TargetFlags::Cpp; - return ParseGraph(toCpp); + return ParseAndTranslateGraph(toCpp); } Result ToLua(const Grammar::Request& request) { Grammar::Request toLua = request; toLua.translationTargetFlags = TargetFlags::Lua; - return ParseGraph(toLua); + return ParseAndTranslateGraph(toLua); } - - } -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.h index 4c59b46280..58123c4d0c 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -18,14 +18,15 @@ namespace ScriptCanvas namespace Translation { - Result ParseGraph(const Grammar::Request& request); + AZ::Outcome ParseGraph(const Grammar::Request& request); + + Result ParseAndTranslateGraph(const Grammar::Request& request); Result ToCPlusPlus(const Grammar::Request& request); Result ToCPlusPlusAndLua(const Grammar::Request& request); - - Result ToLua(const Grammar::Request& request); - - } -} + Result ToLua(const Grammar::Request& request); + + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationResult.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationResult.h index 951518de72..0f98a7ed06 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationResult.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationResult.h @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -41,7 +41,7 @@ namespace ScriptCanvas Cpp = 1 << 1, Hpp = 1 << 2, }; - + // information required at runtime begin execution of the compiled graph from the host struct RuntimeInputs { @@ -51,10 +51,13 @@ namespace ScriptCanvas static void Reflect(AZ::ReflectContext* reflectContext); Grammar::ExecutionStateSelection m_executionSelection = Grammar::ExecutionStateSelection::InterpretedPure; + AZStd::vector m_nodeables; AZStd::vector> m_variables; + // either the entityId was a (member) variable in the source graph, or it got promoted to one during parsing AZStd::vector> m_entityIds; + // Statics required for internal, local values that need non-code constructible initialization, // when the system can't pass in the input from C++. AZStd::vector> m_staticVariables; @@ -84,7 +87,7 @@ namespace ScriptCanvas using ErrorList = AZStd::vector; using Errors = AZStd::unordered_map; using Translations = AZStd::unordered_map; - + AZStd::sys_time_t SumDurations(const Translations& translation); class Result @@ -98,6 +101,7 @@ namespace ScriptCanvas const AZStd::sys_time_t m_translationDuration; Result(AZStd::string invalidSourceInfo); + Result(Result&& source); Result(Grammar::AbstractCodeModelConstPtr model); Result(Grammar::AbstractCodeModelConstPtr model, Translations&& translations, Errors&& errors); @@ -107,7 +111,7 @@ namespace ScriptCanvas AZ::Outcome IsSuccess(TargetFlags flag) const; bool TranslationSucceed(TargetFlags flag) const; }; - + struct LuaAssetResult { AZ::Data::Asset m_scriptAsset; @@ -117,7 +121,5 @@ namespace ScriptCanvas AZStd::sys_time_t m_parseDuration; AZStd::sys_time_t m_translationDuration; }; - - } - -} + } +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.cpp index d2e3a8378f..7a26aed338 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.cpp @@ -166,7 +166,7 @@ namespace ScriptCanvas return TranslationUtilitiesCPP::k_namespaceNameNative; } - AZStd::string_view GetAmazonCopyright() + AZStd::string_view GetCopyright() { return "* Copyright (c) Contributors to the Open 3D Engine Project\n" diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.h index 9e2b9090dd..64c2793e28 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/TranslationUtilities.h @@ -34,7 +34,7 @@ namespace ScriptCanvas AZStd::string EntityIdValueToString(const AZ::EntityId& entityId, const Configuration& config); - AZStd::string_view GetAmazonCopyright(); + AZStd::string_view GetCopyright(); AZStd::string_view GetAutoNativeNamespace(); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp index 43ad3c43f2..aa340f55b9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -104,42 +104,42 @@ namespace ScriptCanvas } } else - if (classElement.GetVersion() < 3) - { - bool exposeAsInputField = false; - classElement.GetChildData(AZ_CRC("ExposeAsInput", 0x0f7879f0), exposeAsInputField); - - if (exposeAsInputField) + if (classElement.GetVersion() < 3) { + bool exposeAsInputField = false; + classElement.GetChildData(AZ_CRC("ExposeAsInput", 0x0f7879f0), exposeAsInputField); + + if (exposeAsInputField) + { + classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd)); + classElement.AddElementWithData(context, "Scope", VariableFlags::Scope::Graph); + } + else + { + AZ::u8 exposureType = VariableFlags::Deprecated::Exposure::Exp_Local; + classElement.GetChildData(AZ_CRC("Exposure", 0x398f29cd), exposureType); + + VariableFlags::Scope scope = VariableFlags::Scope::Graph; + + if ((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut) + { + scope = VariableFlags::Scope::Graph; + } + else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Input) + { + scope = VariableFlags::Scope::Graph; + } + else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Output) + { + scope = VariableFlags::Scope::Function; + } + + classElement.AddElementWithData(context, "Scope", scope); + } + classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd)); - classElement.AddElementWithData(context, "Scope", VariableFlags::Scope::Graph); + classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0)); } - else - { - AZ::u8 exposureType = VariableFlags::Deprecated::Exposure::Exp_Local; - classElement.GetChildData(AZ_CRC("Exposure", 0x398f29cd), exposureType); - - VariableFlags::Scope scope = VariableFlags::Scope::Graph; - - if ((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut) - { - scope = VariableFlags::Scope::Graph; - } - else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Input) - { - scope = VariableFlags::Scope::Graph; - } - else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Output) - { - scope = VariableFlags::Scope::Function; - } - - classElement.AddElementWithData(context, "Scope", scope); - } - - classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd)); - classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0)); - } return true; } @@ -203,8 +203,8 @@ namespace ScriptCanvas editContext->Class("Variable", "Represents a Variable field within a Script Canvas Graph") ->ClassElement(AZ::Edit::ClassElements::EditorData, "") ->Attribute(AZ::Edit::Attributes::Visibility, &GraphVariable::GetVisibility) - ->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &GraphVariable::GetDisplayName) - ->Attribute(AZ::Edit::Attributes::NameLabelOverride, &GraphVariable::GetDisplayName) + ->Attribute(AZ::Edit::Attributes::ChildNameLabelOverride, &GraphVariable::GetVariableName) + ->Attribute(AZ::Edit::Attributes::NameLabelOverride, &GraphVariable::GetVariableName) ->Attribute(AZ::Edit::Attributes::DescriptionTextOverride, &GraphVariable::GetDescriptionOverride) ->DataElement(AZ::Edit::UIHandlers::ComboBox, &GraphVariable::m_InitialValueSource, "Initial Value Source", "Variables can get their values from within the graph or through component properties.") diff --git a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp index 2ba32fb5c9..7d41ce930a 100644 --- a/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Source/SystemComponent.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) Contributors to the Open 3D Engine Project - * + * * SPDX-License-Identifier: Apache-2.0 OR MIT * */ @@ -9,10 +9,11 @@ #include #include +#include #include #include - #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include #include +#include #include #include @@ -53,7 +55,6 @@ namespace ScriptCanvasSystemComponentCpp namespace ScriptCanvas { - void SystemComponent::Reflect(AZ::ReflectContext* context) { Nodeable::Reflect(context); @@ -83,11 +84,16 @@ namespace ScriptCanvas } } + if (AZ::JsonRegistrationContext* jsonContext = azrtti_cast(context)) + { + jsonContext->Serializer() + ->HandlesType(); + } + #if defined(SC_EXECUTION_TRACE_ENABLED) ExecutionLogData::Reflect(context); ExecutionLogAsset::Reflect(context); #endif//defined(SC_EXECUTION_TRACE_ENABLED) - } void SystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) @@ -144,7 +150,7 @@ namespace ScriptCanvas ModPerformanceTracker()->CalculateReports(); Execution::PerformanceTrackingReport report = ModPerformanceTracker()->GetGlobalReport(); - + const double ready = aznumeric_caster(report.timing.initializationTime); const double instant = aznumeric_caster(report.timing.executionTime); const double latent = aznumeric_caster(report.timing.latentTime); @@ -357,11 +363,11 @@ namespace ScriptCanvas auto dataRegistry = ScriptCanvas::GetDataRegistry(); for (const auto& classIter : behaviorContext->m_classes) { - auto createability = GetCreatibility(serializeContext, classIter.second); - if (createability.first != DataRegistry::Createability::None) - { - dataRegistry->RegisterType(classIter.second->m_typeId, createability.second, createability.first); - } + auto createability = GetCreatibility(serializeContext, classIter.second); + if (createability.first != DataRegistry::Createability::None) + { + dataRegistry->RegisterType(classIter.second->m_typeId, createability.second, createability.first); + } } } diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index aef1803e25..8e7a8c0411 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -588,6 +588,8 @@ set(FILES Include/ScriptCanvas/Profiler/Aggregator.cpp Include/ScriptCanvas/Profiler/DrillerEvents.h Include/ScriptCanvas/Profiler/DrillerEvents.cpp + Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h + Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp Include/ScriptCanvas/Data/DataTrait.cpp Include/ScriptCanvas/Data/DataTrait.h Include/ScriptCanvas/Data/PropertyTraits.cpp @@ -621,4 +623,4 @@ set(SKIP_UNITY_BUILD_INCLUSION_FILES Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp -) +) \ No newline at end of file diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake index a3bb843473..0841137435 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake @@ -7,10 +7,12 @@ set(FILES Builder/BuilderSystemComponent.h + Builder/ScriptCanvasBuilder.cpp + Builder/ScriptCanvasBuilder.h Builder/ScriptCanvasBuilderComponent.cpp Builder/ScriptCanvasBuilderComponent.h Builder/ScriptCanvasBuilderWorker.cpp Builder/ScriptCanvasBuilderWorker.h Builder/ScriptCanvasBuilderWorkerUtility.cpp Builder/ScriptCanvasFunctionBuilderWorker.cpp -) +) \ No newline at end of file From fb448124e2f15821c930f6bd3d4871b329ea5baf Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 29 Jun 2021 15:11:22 -0700 Subject: [PATCH 02/16] removed uneccessary prefab senstive code Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Execution/ExecutionContext.cpp | 63 ++++--------------- 1 file changed, 11 insertions(+), 52 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp index 292a9490b8..ebf06f3513 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionContext.cpp @@ -92,60 +92,19 @@ namespace ScriptCanvas // (always overridden) EntityIds { - bool prefabSystemEnabled = false; - AzFramework::ApplicationRequests::Bus::BroadcastResult(prefabSystemEnabled, &AzFramework::ApplicationRequests::IsPrefabSystemEnabled); + AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs + + runtimeData.m_activationInputRange.nodeableCount + + runtimeData.m_activationInputRange.variableCount; - if (prefabSystemEnabled) + const auto entityIdTypeId = azrtti_typeid(); + + for (auto& entityId : activationData.variableOverrides.m_entityIds) { - AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs - + runtimeData.m_activationInputRange.nodeableCount - + runtimeData.m_activationInputRange.variableCount; - - const auto entityIdTypeId = azrtti_typeid(); - - for (auto& entityId : activationData.variableOverrides.m_entityIds) - { - destVariableIter->m_typeId = entityIdTypeId; - destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); - auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); - *entityIdValuePtr = entityId; - ++destVariableIter; - } - } - else - { - AZ::SliceComponent::EntityIdToEntityIdMap loadedEntityIdMap; - AzFramework::EntityContextId owningContextId = AzFramework::EntityContextId::CreateNull(); - AzFramework::EntityIdContextQueryBus::EventResult(owningContextId, forSliceSupportOnly, &AzFramework::EntityIdContextQueries::GetOwningContextId); - if (!owningContextId.IsNull()) - { - AzFramework::SliceEntityOwnershipServiceRequestBus::EventResult(loadedEntityIdMap, owningContextId, &AzFramework::SliceEntityOwnershipServiceRequestBus::Events::GetLoadedEntityIdMap); - } - - AZ::BehaviorValueParameter* destVariableIter = rangeOut.inputs - + runtimeData.m_activationInputRange.nodeableCount - + runtimeData.m_activationInputRange.variableCount; - - const auto entityIdTypeId = azrtti_typeid(); - for (auto& entityId : activationData.variableOverrides.m_entityIds) - { - destVariableIter->m_typeId = entityIdTypeId; - destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); - auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); - - auto iter = loadedEntityIdMap.find(entityId); - if (iter != loadedEntityIdMap.end()) - { - *entityIdValuePtr = iter->second; - } - else - { - *entityIdValuePtr = Data::EntityIDType(); - } - - *entityIdValuePtr = entityId; - ++destVariableIter; - } + destVariableIter->m_typeId = entityIdTypeId; + destVariableIter->m_value = destVariableIter->m_tempData.allocate(sizeof(Data::EntityIDType), AZStd::alignment_of::value, 0); + auto entityIdValuePtr = reinterpret_cast*>(destVariableIter->m_value); + *entityIdValuePtr = entityId; + ++destVariableIter; } } From 355776d3a96a8b2f1d8dde0b02559464d7995929 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 29 Jun 2021 17:25:23 -0700 Subject: [PATCH 03/16] Add versioning updates for prefab conversion, and PR clean up & nitpicks Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Builder/ScriptCanvasBuilder.cpp | 8 +- .../Code/Builder/ScriptCanvasBuilderWorker.h | 2 + .../EditorScriptCanvasComponent.cpp | 88 +++++++++++++++---- .../Code/Include/ScriptCanvas/Core/Datum.cpp | 30 +++---- .../Grammar/AbstractCodeModel.cpp | 8 +- .../ScriptUserDataSerializer.cpp | 17 ++-- .../ScriptCanvas/Variable/GraphVariable.cpp | 3 + 7 files changed, 111 insertions(+), 45 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index ff0fdf6273..d6ee28af9e 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -200,7 +200,11 @@ namespace ScriptCanvasBuilder for (size_t index = 0; index != buildOverrides.m_variables.size(); ++index) { auto& variable = buildOverrides.m_variables[index]; - auto iter = AZStd::find_if(buildOverrides.m_overrides.begin(), buildOverrides.m_overrides.end(), [&variable](auto& candidate) { return candidate.GetVariableId() == variable.GetVariableId(); }); + auto iter = AZStd::find_if + ( buildOverrides.m_overrides.begin() + , buildOverrides.m_overrides.end() + , [&variable](auto& candidate) { return candidate.GetVariableId() == variable.GetVariableId(); }); + if (iter != buildOverrides.m_overrides.end()) { if (iter->GetDatum()) @@ -265,7 +269,7 @@ namespace ScriptCanvasBuilder } AzToolsFramework::AssetSystemRequestBus::BroadcastResult - (resultFound + ( resultFound , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourceUUID , editorAssetId.m_guid , assetInfo diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h index 90dfb843b9..465be7760b 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.h @@ -55,6 +55,8 @@ namespace ScriptCanvasBuilder DependencyArguments, DependencyRequirementsData, AddAssetDependencySearch, + PrefabIntegration, + CorrectGraphVariableVersion, // add new entries above Current, }; diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp index 56a170f851..a1d90839f8 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp @@ -31,6 +31,18 @@ #include #include + +namespace EditorScriptCanvasComponentCpp +{ + enum Version + { + PrefabIntegration = 10, + + // add description above + Current + }; +} + namespace ScriptCanvasEditor { static bool EditorScriptCanvasComponentVersionConverter(AZ::SerializeContext& serializeContext, AZ::SerializeContext::DataElementNode& rootElement) @@ -73,6 +85,63 @@ namespace ScriptCanvasEditor rootElement.RemoveElementByName(AZ_CRC("m_variableEntityIdMap", 0xdc6c75a8)); } + if (rootElement.GetVersion() <= EditorScriptCanvasComponentCpp::Version::PrefabIntegration) + { + auto variableDataElementIndex = rootElement.FindElement(AZ_CRC_CE("m_variableData")); + if (variableDataElementIndex == -1) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: 'm_variableData' index was missing"); + return false; + } + + auto& variableDataElement = rootElement.GetSubElement(variableDataElementIndex); + + ScriptCanvas::EditableVariableData editableData; + if (!variableDataElement.GetData(editableData)) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_variableData'"); + return false; + } + + auto scriptCanvasAssetHolderElementIndex = rootElement.FindElement(AZ_CRC_CE("m_assetHolder")); + if (scriptCanvasAssetHolderElementIndex == -1) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: 'm_assetHolder' index was missing"); + return false; + } + + auto& scriptCanvasAssetHolderElement = rootElement.GetSubElement(scriptCanvasAssetHolderElementIndex); + + ScriptCanvasAssetHolder assetHolder; + if (!scriptCanvasAssetHolderElement.GetData(assetHolder)) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: could not retrieve old 'm_assetHolder'"); + return false; + } + + rootElement.RemoveElement(variableDataElementIndex); + + if (!rootElement.AddElementWithData(serializeContext, "runtimeDataIsValid", true)) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'runtimeDataIsValid'"); + return false; + } + + ScriptCanvasBuilder::BuildVariableOverrides overrides; + overrides.m_source = AZ::Data::Asset(assetHolder.GetAssetId(), assetHolder.GetAssetType(), assetHolder.GetAssetHint());; + + for (auto& variable : editableData.GetVariables()) + { + overrides.m_overrides.push_back(variable.m_graphVariable); + } + + if (!rootElement.AddElementWithData(serializeContext, "runtimeDataOverrides", overrides)) + { + AZ_Error("ScriptCanvas", false, "EditorScriptCanvasComponent conversion failed: failed to add 'runtimeDataOverrides'"); + return false; + } + } + return true; } @@ -82,7 +151,7 @@ namespace ScriptCanvasEditor if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(10, &EditorScriptCanvasComponentVersionConverter) + ->Version(EditorScriptCanvasComponentCpp::Version::Current, &EditorScriptCanvasComponentVersionConverter) ->Field("m_name", &EditorScriptCanvasComponent::m_name) ->Field("m_assetHolder", &EditorScriptCanvasComponent::m_scriptCanvasAssetHolder) ->Field("runtimeDataIsValid", &EditorScriptCanvasComponent::m_runtimeDataIsValid) @@ -213,18 +282,7 @@ namespace ScriptCanvasEditor if (fileAssetId.IsValid()) { AssetTrackerNotificationBus::Handler::BusConnect(fileAssetId); - - ScriptCanvasMemoryAsset::pointer memoryAsset; - AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, fileAssetId); - - if (memoryAsset && memoryAsset->GetAsset().GetStatus() == AZ::Data::AssetData::AssetStatus::Ready) - { - OnScriptCanvasAssetReady(memoryAsset); - } - else - { - AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetType(), nullptr); - } + AzToolsFramework::ToolsApplicationNotificationBus::Broadcast(&AzToolsFramework::ToolsApplicationEvents::InvalidatePropertyDisplay, AzToolsFramework::Refresh_EntireTree_NewContent); } } @@ -251,7 +309,7 @@ namespace ScriptCanvasEditor auto assetTreeOutcome = LoadEditorAssetTree(m_scriptCanvasAssetHolder.GetAssetId(), m_scriptCanvasAssetHolder.GetAssetHint()); if (!assetTreeOutcome.IsSuccess()) { - AZ_Warning("ScriptCanvas", false, AZStd::string::format("EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str()).c_str()); + AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", assetTreeOutcome.GetError().c_str()); return; } @@ -260,7 +318,7 @@ namespace ScriptCanvasEditor auto parseOutcome = ParseEditorAssetTree(editorAssetTree); if (!parseOutcome.IsSuccess()) { - AZ_Warning("ScriptCanvas", false, AZStd::string::format("EditorScriptCanvasComponent::BuildGameEntityData failed: %s", parseOutcome.GetError().c_str()).c_str()); + AZ_Warning("ScriptCanvas", false, "EditorScriptCanvasComponent::BuildGameEntityData failed: %s", parseOutcome.GetError().c_str()); return; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp index 3c70031af0..9a785dceba 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Datum.cpp @@ -209,7 +209,7 @@ namespace DatumHelpers } else if (typeID == azrtti_typeid()) { - target = BehaviorContextObject::Create(AZ::Vector2(static_cast(sourceVector.GetX()), static_cast(sourceVector.GetY())), behaviorClass); + target = BehaviorContextObject::Create(AZ::Vector2((sourceVector.GetX()), (sourceVector.GetY())), behaviorClass); } else if (typeID == azrtti_typeid()) { @@ -264,7 +264,7 @@ namespace DatumHelpers } else if (typeID == azrtti_typeid()) { - target = BehaviorContextObject::Create(AZ::Vector2(static_cast(sourceVector.GetX()), static_cast(sourceVector.GetY())), behaviorClass); + target = BehaviorContextObject::Create(AZ::Vector2((sourceVector.GetX()), (sourceVector.GetY())), behaviorClass); } else if (typeID == azrtti_typeid()) { @@ -2478,7 +2478,7 @@ namespace ScriptCanvas AZStd::string Datum::ToStringColor(const Data::ColorType& c) const { - return AZStd::string::format("(r=%.7f,g=%.7f,b=%.7f,a=%.7f)", static_cast(c.GetR()), static_cast(c.GetG()), static_cast(c.GetB()), static_cast(c.GetA())); + return AZStd::string::format("(r=%.7f,g=%.7f,b=%.7f,a=%.7f)", (c.GetR()), (c.GetG()), (c.GetB()), (c.GetA())); } bool Datum::ToStringBehaviorClassObject(Data::StringType& stringOut) const @@ -2555,9 +2555,9 @@ namespace ScriptCanvas AZ::Vector3 eulerRotation = AZ::ConvertTransformToEulerDegrees(AZ::Transform::CreateFromQuaternion(source)); return AZStd::string::format ("(Pitch: %5.2f, Roll: %5.2f, Yaw: %5.2f)" - , static_cast(eulerRotation.GetX()) - , static_cast(eulerRotation.GetY()) - , static_cast(eulerRotation.GetZ())); + , (eulerRotation.GetX()) + , (eulerRotation.GetY()) + , (eulerRotation.GetZ())); } AZStd::string Datum::ToStringTransform(const Data::TransformType& source) const @@ -2570,8 +2570,8 @@ namespace ScriptCanvas ("(Position: X: %f, Y: %f, Z: %f," " Rotation: X: %f, Y: %f, Z: %f," " Scale: %f)" - , static_cast(pos.GetX()), static_cast(pos.GetY()), static_cast(pos.GetZ()) - , static_cast(rotation.GetX()), static_cast(rotation.GetY()), static_cast(rotation.GetZ()) + , (pos.GetX()), (pos.GetY()), (pos.GetZ()) + , (rotation.GetX()), (rotation.GetY()), (rotation.GetZ()) , scale); } @@ -2587,19 +2587,19 @@ namespace ScriptCanvas { return AZStd::string::format ("(X: %f, Y: %f, Z: %f)" - , static_cast(source.GetX()) - , static_cast(source.GetY()) - , static_cast(source.GetZ())); + , (source.GetX()) + , (source.GetY()) + , (source.GetZ())); } AZStd::string Datum::ToStringVector4(const AZ::Vector4& source) const { return AZStd::string::format ("(X: %f, Y: %f, Z: %f, W: %f)" - , static_cast(source.GetX()) - , static_cast(source.GetY()) - , static_cast(source.GetZ()) - , static_cast(source.GetW())); + , (source.GetX()) + , (source.GetY()) + , (source.GetZ()) + , (source.GetW())); } AZ::Outcome Datum::CallBehaviorContextMethod(const AZ::BehaviorMethod* method, AZ::BehaviorValueParameter* params, unsigned int numExpectedArgs) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 1851b5e65d..a42f624f01 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -1226,8 +1226,8 @@ namespace ScriptCanvas (nodeling->GetEntityId() , nullptr , AZStd::string::format - ("%s is the name of multiple In Nodelings in a subgraph,\n" - "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.data())); + ( "%s is the name of multiple In Nodelings in a subgraph,\n" + "this will result in a difficult or impossible to use Function Node when used in another graph", displayName.c_str())); return; } else @@ -1355,8 +1355,8 @@ namespace ScriptCanvas if (ExecutionContainsCycles(node, outSlot)) { AddError(nullptr, aznew Internal::ParseError(node.GetEntityId(), AZStd::string::format - ("Execution cycle detected (see connections to %s-%s. Use a looping node like While or For" - , node.GetDebugName().data(), outSlot.GetName().data()).data())); + ( "Execution cycle detected (see connections to %s-%s. Use a looping node like While or For" + , node.GetDebugName().c_str(), outSlot.GetName().c_str()).c_str())); return true; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index 207acafd82..f626cb1da2 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -5,10 +5,9 @@ * */ -#include "ScriptUserDataSerializer.h" - #include #include +#include using namespace ScriptCanvas; @@ -31,10 +30,10 @@ namespace AZ JsonSerializationResult::ResultCode result(JSR::Tasks::ReadField); AZ::Uuid typeId = AZ::Uuid::CreateNull(); - auto typeIdMember = inputValue.FindMember("$type"); + auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load the $type member"); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier).c_str()); } result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); @@ -46,13 +45,13 @@ namespace AZ outputVariable->value = context.GetSerializeContext()->CreateAny(typeId); if (outputVariable->value.empty() || outputVariable->value.type() != typeId) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); } result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context)); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted - ? "ScriptUserDataSerializer Store finished loading RuntimeVariable" - : "ScriptUserDataSerializer Store failed to load RuntimeVariable"); + ? "ScriptUserDataSerializer Load finished loading RuntimeVariable" + : "ScriptUserDataSerializer Load failed to load RuntimeVariable"); } JsonSerializationResult::Result ScriptUserDataSerializer::Store @@ -91,7 +90,7 @@ namespace AZ rapidjson::Value typeValue; typeValue.SetString(azTypeString.begin(), azTypeString.length(), context.GetJsonAllocator()); result.Combine(StoreTypeId(typeValue, inputAnyPtr->type(), context)); - outputValue.AddMember("$type", typeValue, context.GetJsonAllocator()); + outputValue.AddMember("$type", AZStd::move(typeValue), context.GetJsonAllocator()); } result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context)); @@ -101,4 +100,4 @@ namespace AZ : "ScriptUserDataSerializer Store failed to save RuntimeVariable"); } -} \ No newline at end of file +} diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp index aa340f55b9..57c40111a6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp @@ -102,6 +102,9 @@ namespace ScriptCanvas classElement.RemoveElementByName(AZ_CRC_CE("Scope")); classElement.AddElementWithData(context, "InitialValueSource", VariableFlags::InitialValueSource::Component); } + + classElement.RemoveElementByName(AZ_CRC("ExposeAsInput", 0x0f7879f0)); + classElement.RemoveElementByName(AZ_CRC("Exposure", 0x398f29cd)); } else if (classElement.GetVersion() < 3) From 9d9205d067bfb88bc9969f6a242d7d7eb8b904a7 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 29 Jun 2021 18:42:32 -0700 Subject: [PATCH 04/16] SC user nodeables now use __index method does not report error on (allowable) nil table entries LYN-3664 Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/AzCore/Script/ScriptContext.cpp | 116 ++++++++++++++---- .../AzCore/Script/ScriptContextAttributes.h | 1 + .../Include/ScriptCanvas/Core/Nodeable.cpp | 1 + 3 files changed, 91 insertions(+), 27 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp index 0dd24261b8..d3d95b3078 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContext.cpp @@ -689,6 +689,81 @@ namespace AZ return 1; } + int Class__IndexAllowNil(lua_State* l) + { + LSV_BEGIN(l, 1); + + // calling format __index(table,key) + lua_getmetatable(l, -2); // load the userdata metatable + int metaTableIndex = lua_gettop(l); + + // Check if the key is string, if so we expect it to be a function or property name + // otherwise we allow users to provide custom index handlers + // Technically we can allow strings too, but it will clash with function/property names and it be hard to figure + // out what is going on from with in the system. + if (lua_type(l, -2) == LUA_TSTRING) + { + lua_pushvalue(l, -2); // duplicate the key + lua_rawget(l, -2); // load the value at this index + } + else + { + lua_pushliteral(l, "__AZ_Index"); + lua_rawget(l, -2); // check if the user provided custom Index method in the class metatable + if (lua_isnil(l, -1)) // if not report an error + { + lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error + if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable + { + lua_pop(l, 1); + lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX); + } + ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Invalid index type [], should be string! '%s:%s'!", lua_tostring(l, -1), lua_tostring(l, -4)); + } + else + { + // if we have custom index handler + lua_pushvalue(l, -4); // duplicate the table (class pointer) + lua_pushvalue(l, -4); // duplicate the index value for the call + lua_call(l, 2, 1); // call the function + } + + lua_remove(l, metaTableIndex); // remove the metatable + return 1; + } + + if (!lua_isnil(l, -1)) + { + if (lua_tocfunction(l, -1) == &Internal::LuaPropertyTagHelper) // if it's a property + { + lua_getupvalue(l, -1, 1); // push on the stack the getter function + lua_remove(l, -2); // remove property object + + if (lua_isnil(l, -1)) + { + lua_rawgeti(l, -2, AZ_LUA_CLASS_METATABLE_NAME_INDEX); // load the class name for a better error + if (!lua_isstring(l, -1)) // if we failed it means we are the base metatable + { + lua_pop(l, 1); + lua_rawgeti(l, 1, AZ_LUA_CLASS_METATABLE_NAME_INDEX); + } + + ScriptContext::FromNativeContext(l)->Error(ScriptContext::ErrorType::Warning, true, "Property '%s:%s' is write only", lua_tostring(l, -1), lua_tostring(l, -4)); + lua_pop(l, 1); // pop class name + } + else + { + lua_pushvalue(l, -4); // copy the user data to be passed as a this pointer. + lua_call(l, 1, 1); // call a function with one argument (this pointer) and 1 result + } + } + } + + lua_remove(l, metaTableIndex); // remove the metatable + return 1; + } + + //========================================================================= // Class__NewIndex // [3/22/2012] @@ -826,30 +901,6 @@ namespace AZ return 1; } - //========================================================================= - // ClassMetatable__Index - // [3/24/2012] - //========================================================================= - int ClassMetatable__Index(lua_State* l) - { - // since the Class__Index is generic function (ask for the class metatable) - // we can reuse the code for the base metatable (which is a metatable - // of the class metatable) - return Class__Index(l); - } - - //========================================================================= - // ClassMetatable__NewIndex - // [3/30/2012] - //========================================================================= - int ClassMetatable__NewIndex(lua_State* l) - { - // since the Class__NewIndex is generic function (ask for the class metatable) - // we can reuse the code for the base metatable (which is a metatable - // of the class metatable) - return Class__NewIndex(l); - } - inline size_t BufferStringCopy(const char* source, char* destination, size_t destinationSize) { size_t srcLen = strlen(source); @@ -5053,9 +5104,20 @@ LUA_API const Node* lua_getDummyNode() lua_pushcclosure(m_lua, &DefaultBehaviorCaller::Destroy, 0); lua_rawset(m_lua, -3); - lua_pushliteral(m_lua, "__index"); - lua_pushcclosure(m_lua, &Internal::Class__Index, 0); - lua_rawset(m_lua, -3); + { + lua_pushliteral(m_lua, "__index"); + + if (FindAttribute(Script::Attributes::UseClassIndexAllowNil, behaviorClass->m_attributes)) + { + lua_pushcclosure(m_lua, &Internal::Class__IndexAllowNil, 0); + } + else + { + lua_pushcclosure(m_lua, &Internal::Class__Index, 0); + } + + lua_rawset(m_lua, -3); + } lua_pushliteral(m_lua, "__newindex"); lua_pushcclosure(m_lua, &Internal::Class__NewIndex, 0); diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h b/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h index 2970ee2e67..76018f3ed0 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h @@ -29,6 +29,7 @@ namespace AZ const static AZ::Crc32 Deprecated = AZ_CRC("Deprecated", 0xfe49a138); ///< Marks a reflected class, method, EBus or property as deprecated. const static AZ::Crc32 DisallowBroadcast = AZ_CRC("DisallowBroadcast", 0x389b0ac7); ///< Marks a reflected EBus as not allowing Broadcasts, only Events. const static AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value + const static AZ::Crc32 UseClassIndexAllowNil = AZ_CRC_CE("UseClassIndexAllowNil"); ///< Use the Class__IndexAllowNil method, which will not report an error on accessing undeclared values (allows for nil) //! Attribute which stores BehaviorAzEventDescription structure which contains //! the script name of an AZ::Event and the name of it's parameter arguments diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp index bdb8576d8f..868751d2a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Nodeable.cpp @@ -79,6 +79,7 @@ namespace ScriptCanvas behaviorContext->Class() ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List) ->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent) + ->Attribute(AZ::Script::Attributes::UseClassIndexAllowNil, AZ::AttributeIsValid::IfPresent) ->Constructor() ->Method("Deactivate", &Nodeable::Deactivate) ->Method("InitializeExecutionState", &Nodeable::InitializeExecutionState) From 5b7b9897335f379c2844cc7f7572f3ef63bf3d72 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 11:44:25 -0700 Subject: [PATCH 05/16] use more constexpr in ScriptCanvasAttributes.h, remove superfluous string use in SC user data serialization Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/Script/ScriptContextAttributes.h | 48 +++++++++---------- .../ScriptUserDataSerializer.cpp | 6 +-- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h b/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h index 76018f3ed0..734b5e3bae 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h +++ b/Code/Framework/AzCore/AzCore/Script/ScriptContextAttributes.h @@ -16,20 +16,20 @@ namespace AZ { namespace Attributes { - const static AZ::Crc32 Ignore = AZ_CRC("ScriptIgnore", 0xeb7615e1); ///< Don't use the element in the script reflection - const static AZ::Crc32 ClassNameOverride = AZ_CRC("ScriptClassNameOverride", 0x891238a3); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name - const static AZ::Crc32 MethodOverride = AZ_CRC("ScriptFunctionOverride", 0xf89a7882); ///< Use a custom function in the attribute instead of the function - const static AZ::Crc32 ConstructorOverride = AZ_CRC("ConstructorOverride", 0xef5ce4aa); ///< You can provide a custom constructor to be called when created from Lua script - const static AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals - const static AZ::Crc32 GenericConstructorOverride = AZ_CRC("GenericConstructorOverride", 0xe6a1698e); ///< You can provide a custom constructor to be called when creating a script - const static AZ::Crc32 ReaderWriterOverride = AZ_CRC("ReaderWriterOverride", 0x1ad9ce2a); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM - const static AZ::Crc32 ConstructibleFromNil = AZ_CRC("ConstructibleFromNil", 0x23908169); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided. - const static AZ::Crc32 ToolTip = AZ_CRC("ToolTip", 0xa1b95fb0); ///< Add a tooltip for a method/event/property - const static AZ::Crc32 Category = AZ_CRC("Category", 0x064c19c1); ///< Provide a category to allow for partitioning/sorting/ordering of the element - const static AZ::Crc32 Deprecated = AZ_CRC("Deprecated", 0xfe49a138); ///< Marks a reflected class, method, EBus or property as deprecated. - const static AZ::Crc32 DisallowBroadcast = AZ_CRC("DisallowBroadcast", 0x389b0ac7); ///< Marks a reflected EBus as not allowing Broadcasts, only Events. - const static AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value - const static AZ::Crc32 UseClassIndexAllowNil = AZ_CRC_CE("UseClassIndexAllowNil"); ///< Use the Class__IndexAllowNil method, which will not report an error on accessing undeclared values (allows for nil) + static constexpr AZ::Crc32 Ignore = AZ_CRC_CE("ScriptIgnore"); ///< Don't use the element in the script reflection + static constexpr AZ::Crc32 ClassNameOverride = AZ_CRC_CE("ScriptClassNameOverride"); ///< Provide a custom name for script reflection, that doesn't match the behavior Context name + static constexpr AZ::Crc32 MethodOverride = AZ_CRC_CE("ScriptFunctionOverride"); ///< Use a custom function in the attribute instead of the function + static constexpr AZ::Crc32 ConstructorOverride = AZ_CRC_CE("ConstructorOverride"); ///< You can provide a custom constructor to be called when created from Lua script + static constexpr AZ::Crc32 EventHandlerCreationFunction = AZ_CRC_CE("EventHandlerCreationFunction"); ///< helps create a handler for any script target so that script functions can be used for AZ::Event signals + static constexpr AZ::Crc32 GenericConstructorOverride = AZ_CRC_CE("GenericConstructorOverride"); ///< You can provide a custom constructor to be called when creating a script + static constexpr AZ::Crc32 ReaderWriterOverride = AZ_CRC_CE("ReaderWriterOverride"); ///< paired with \ref ScriptContext::CustomReaderWriter allows you to customize read/write to Lua VM + static constexpr AZ::Crc32 ConstructibleFromNil = AZ_CRC_CE("ConstructibleFromNil"); ///< Applied to classes. Value (bool) specifies if the class be default constructed when nil is provided. + static constexpr AZ::Crc32 ToolTip = AZ_CRC_CE("ToolTip"); ///< Add a tooltip for a method/event/property + static constexpr AZ::Crc32 Category = AZ_CRC_CE("Category"); ///< Provide a category to allow for partitioning/sorting/ordering of the element + static constexpr AZ::Crc32 Deprecated = AZ_CRC_CE("Deprecated"); ///< Marks a reflected class, method, EBus or property as deprecated. + static constexpr AZ::Crc32 DisallowBroadcast = AZ_CRC_CE("DisallowBroadcast"); ///< Marks a reflected EBus as not allowing Broadcasts, only Events. + static constexpr AZ::Crc32 ClassConstantValue = AZ_CRC_CE("ClassConstantValue"); ///< Indicates the property is backed by a constant value + static constexpr AZ::Crc32 UseClassIndexAllowNil = AZ_CRC_CE("UseClassIndexAllowNil"); ///< Use the Class__IndexAllowNil method, which will not report an error on accessing undeclared values (allows for nil) //! Attribute which stores BehaviorAzEventDescription structure which contains //! the script name of an AZ::Event and the name of it's parameter arguments @@ -40,11 +40,11 @@ namespace AZ static constexpr AZ::Crc32 EventParameterTypes = AZ_CRC_CE("EventParameterTypes"); ///< Recommends that the Lua runtime look up the member function in the meta table of the first argument, rather than in the original table - const static AZ::Crc32 TreatAsMemberFunction = AZ_CRC("TreatAsMemberFunction", 0x64be831a); + static constexpr AZ::Crc32 TreatAsMemberFunction = AZ_CRC_CE("TreatAsMemberFunction"); ///< This attribute can be attached to the EditContext Attribute of a reflected class, the BehaviorContext Attribute of a reflected class, method, ebus or property. ///< ExcludeFlags can be used to prevent elements from appearing in List, Documentation, etc... - const static AZ::Crc32 ExcludeFrom = AZ_CRC("ExcludeFrom", 0xa98972fe); + static constexpr AZ::Crc32 ExcludeFrom = AZ_CRC_CE("ExcludeFrom"); enum ExcludeFlags : AZ::u64 { List = 1 << 0, //< The reflected item will be excluded from any list (e.g. node palette) @@ -55,7 +55,7 @@ namespace AZ }; //! Used to specify the usage of a Behavior Context element (e.g. Class or EBus) designed for automation scripts - const static AZ::Crc32 Scope = AZ_CRC("Scope", 0x00af55d3); + static constexpr AZ::Crc32 Scope = AZ_CRC_CE("Scope"); enum class ScopeFlags : AZ::u64 { Launcher = 1 << 0, //< a type meant for game run-time Launcher client (default value) @@ -64,15 +64,15 @@ namespace AZ }; //! Provide a partition hierarchy in a string dotted notation to namespace a script element - const static AZ::Crc32 Module = AZ_CRC("Module", 0x0c242628); + static constexpr AZ::Crc32 Module = AZ_CRC_CE("Module"); //! Provide an alternate name for script elements such as helpful PEP8 Python methods and property aliases - const static AZ::Crc32 Alias = AZ_CRC("Alias", 0xe16c6b94); + static constexpr AZ::Crc32 Alias = AZ_CRC_CE("Alias"); - const static AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC("ScriptEventParam", 0xa41e4cb0); - const static AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC("ScriptEventReturn", 0xf89b5337); + static constexpr AZ::Crc32 EnableAsScriptEventParamType = AZ_CRC_CE("ScriptEventParam"); + static constexpr AZ::Crc32 EnableAsScriptEventReturnType = AZ_CRC_CE("ScriptEventReturn"); - const static AZ::Crc32 Storage = AZ_CRC("ScriptStorage", 0xcd95b44d); + static constexpr AZ::Crc32 Storage = AZ_CRC_CE("ScriptStorage"); enum class StorageType { ScriptOwn, // default, Host allocated memory, Lua will destruct object, Lua will free host-memory via host-supplied function @@ -80,7 +80,7 @@ namespace AZ Value, // Object is Lua allocated memory, Lua will destruct object, Lua will free Lua-memory }; - const static AZ::Crc32 Operator = AZ_CRC("ScriptOperator", 0xfee681b6); + static constexpr AZ::Crc32 Operator = AZ_CRC_CE("ScriptOperator"); enum class OperatorType { // note storage policy can be T*,T (only if we store raw pointers), shared_ptr, intrusive pointer @@ -101,7 +101,7 @@ namespace AZ IndexWrite, // given a key/index and a value, you can store it in the class }; - const static AZ::Crc32 AssetType = AZ_CRC("AssetType", 0xabbf8d5f); ///< Provide an asset type for a generic AssetId method + static constexpr AZ::Crc32 AssetType = AZ_CRC_CE("AssetType"); ///< Provide an asset type for a generic AssetId method } // Attributes } // Script diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index f626cb1da2..62e361da93 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -33,7 +33,7 @@ namespace AZ auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier).c_str()); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier)); } result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); @@ -86,13 +86,11 @@ namespace AZ outputValue.SetObject(); { - auto azTypeString = inputAnyPtr->type().ToString(); rapidjson::Value typeValue; - typeValue.SetString(azTypeString.begin(), azTypeString.length(), context.GetJsonAllocator()); result.Combine(StoreTypeId(typeValue, inputAnyPtr->type(), context)); outputValue.AddMember("$type", AZStd::move(typeValue), context.GetJsonAllocator()); } - + result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context)); return context.Report(result, result.GetProcessing() != JSR::Processing::Halted From df02813cd4c84b9cd7505f06d6fcbbc70377f077 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 11:58:04 -0700 Subject: [PATCH 06/16] Hide ExecutionState methods from SC, Fixes LYN-4900 Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Include/ScriptCanvas/Execution/ExecutionState.cpp | 2 ++ .../Execution/Interpreted/ExecutionStateInterpreted.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp index aebb3ed20e..e60b4b1b82 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/ExecutionState.cpp @@ -92,6 +92,8 @@ namespace ScriptCanvas if (auto behaviorContext = azrtti_cast(reflectContext)) { behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List) + ->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent) ->Method("GetEntityId", &ExecutionState::GetEntityId) ->Method("GetScriptCanvasId", &ExecutionState::GetScriptCanvasId) ->Method("ToString", &ExecutionState::ToString) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp index d7cc05cf1b..98e6f17d17 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Execution/Interpreted/ExecutionStateInterpreted.cpp @@ -132,6 +132,8 @@ namespace ScriptCanvas if (AZ::BehaviorContext* behaviorContext = azrtti_cast(reflectContext)) { behaviorContext->Class() + ->Attribute(AZ::Script::Attributes::ExcludeFrom, AZ::Script::Attributes::ExcludeFlags::List) + ->Attribute(AZ::ScriptCanvasAttributes::VariableCreationForbidden, AZ::AttributeIsValid::IfPresent) ; } } From 917dacb61e2e8560eb58d334f3c7be6253bb4301 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 12:10:51 -0700 Subject: [PATCH 07/16] Added comment explaining state of progress of SC --> C++ Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Include/ScriptCanvas/Translation/Translation.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp index b44e438ba0..a1628a59af 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Translation/Translation.cpp @@ -133,6 +133,10 @@ namespace ScriptCanvas } } + // Translation to C++ (executed via BehaviorContext calls) has been demonstrated in the past and is partially in progress. + // These calls allow for users to execute multiple translations from the same abstract code model. + // More work is required to complete all the latest features of the ACM, and do integrate output files into the build. + // // if (targetFlags & (TargetFlags::Cpp | TargetFlags::Hpp)) // { // auto outcomeCPP = TranslationCPP::ToCPlusPlus(*model.get(), rawSave); From 0136c924674d6eb1550d69e7b5c158f9adb78f21 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 16:55:26 -0700 Subject: [PATCH 08/16] PR white space feedback, better Lua print error message, fix ACM static variable culling Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/AzCore/Script/ScriptDebug.cpp | 5 +- .../Grammar/AbstractCodeModel.cpp | 67 +++++++++++++------ .../ScriptCanvas/Grammar/AbstractCodeModel.h | 2 + .../ScriptUserDataSerializer.cpp | 2 +- .../Code/scriptcanvasgem_common_files.cmake | 3 +- ...scriptcanvasgem_editor_builder_files.cmake | 2 +- 6 files changed, 52 insertions(+), 29 deletions(-) diff --git a/Code/Framework/AzCore/AzCore/Script/ScriptDebug.cpp b/Code/Framework/AzCore/AzCore/Script/ScriptDebug.cpp index 2f2ac5bdfa..c10f6d7826 100644 --- a/Code/Framework/AzCore/AzCore/Script/ScriptDebug.cpp +++ b/Code/Framework/AzCore/AzCore/Script/ScriptDebug.cpp @@ -24,7 +24,6 @@ namespace AZ //========================================================================= AZStd::string ExtractUserMessage(const ScriptDataContext& dc) { - AZStd::string userMessage = "Condition failed"; const int argCount = dc.GetNumArguments(); if (argCount > 0 && dc.IsString(argCount - 1)) { @@ -33,12 +32,12 @@ namespace AZ { if (value) { - userMessage = value; + return value; } } } - return userMessage; + return "ExtractUserMessage from print/Debug.Log/Warn/Error/Assert failed. Consider wrapping your argument in tostring()."; } //========================================================================= diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index a42f624f01..e971375e15 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -2258,12 +2258,16 @@ namespace ScriptCanvas m_variableScopeMeaning = VariableScopeMeaning_LegacyFunctions::ValueInitialization; } #endif + // The Order Matters: begin + + // add all data to the ACM for easy look up in input/output processing for ACM nodes AddAllVariablesPreParse(); if (!IsErrorFree()) { return; } + // parse basic editor nodes as they may add implicit variables for (auto& nodeEntity : m_source.m_graphData->m_nodes) { if (nodeEntity) @@ -2296,18 +2300,27 @@ namespace ScriptCanvas return; } + // parse the implicit variables added by ebus handling syntax sugar ParseAutoConnectedEBusHandlerVariables(); + // all possible data is available, now parse execution, starting with "main", currently keyed to RuntimeComponent::Activate Parse(m_startNodes); - + // parse any function introduced by nodes other than On Graph Start/"main" for (auto node : m_possibleExecutionRoots) { ParseExecutionTreeRoots(*node); } - + // parse functions introduced by variable change events ParseVariableHandling(); + // parse all user function and function object signatures ParseUserFunctionTopology(); - ParseConstructionInputVariables(); + // culls unused variables, and determine whether the the graph defines an object or static functionality ParseExecutionCharacteristics(); + // now that variables have been culled, determined what data needs to be initialized by an external source + ParseConstructionInputVariables(); + // now that externally initialized data has been identified, associate local, static initializers with individual functions + ParseFunctionLocalStaticUseage(); + + // The Order Matters: end // from here on, nothing more needs to happen during simple parsing // for example, in the editor, to get validation on syntax based effects for the view @@ -2315,7 +2328,10 @@ namespace ScriptCanvas if (IsErrorFree()) { + // the graph could have used several user graphs which required construction, and maybe multiple instances of the same user asset + // this will create indices for those nodes to be able to pass in the proper entry in the construction argument tree at translation and runtime ParseDependenciesAssetIndicies(); + // protect all names against keyword collision and language naming violations ConvertNamesToIdentifiers(); if (m_source.m_addDebugInfo) @@ -4189,6 +4205,32 @@ namespace ScriptCanvas ParseExecutionLoop(execution); } + void AbstractCodeModel::ParseFunctionLocalStaticUseage() + { + for (auto execution : ModAllExecutionRoots()) + { + if (auto localVariables = GetLocalVariables(execution)) + { + for (auto variable : *localVariables) + { + if (const AZStd::pair* pair = FindStaticVariable(variable)) + { + auto& localStatics = ModStaticVariablesNames(execution); + auto iter = AZStd::find_if + ( localStatics.begin() + , localStatics.end() + , [&](const auto& candidate) { return candidate.first == variable; }); + + if (iter == localStatics.end()) + { + localStatics.push_back(*pair); + } + } + } + } + } + } + void AbstractCodeModel::ParseImplicitVariables(const Node& node) { if (IsCycle(node)) @@ -5232,27 +5274,8 @@ namespace ScriptCanvas TraverseTree(execution, listener); const auto& usage = listener.GetUsedVariables(); const bool usesOnlyLocalVariables = usage.memberVariables.empty() && usage.implicitMemberVariables.empty(); - m_variableUse.localVariables.insert(usage.localVariables.begin(), usage.localVariables.end()); m_variableUse.memberVariables.insert(usage.memberVariables.begin(), usage.memberVariables.end()); - - for (auto variable : m_variableUse.localVariables) - { - if (const AZStd::pair* pair = FindStaticVariable(variable)) - { - auto& localStatics = ModStaticVariablesNames(execution); - auto iter = AZStd::find_if - (localStatics.begin() - , localStatics.end() - , [&](const auto& candidate) { return candidate.first == variable; }); - - if (iter == localStatics.end()) - { - localStatics.push_back(*pair); - } - } - } - m_variableUseByExecution.emplace(execution, listener.MoveUsedVariables()); return (!usage.usesExternallyInitializedVariables) && usesOnlyLocalVariables && listener.IsPure(); } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h index f87913d47a..a5c55a7c4f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.h @@ -366,6 +366,8 @@ namespace ScriptCanvas void ParseExecutionWhileLoop(ExecutionTreePtr execution); + void ParseFunctionLocalStaticUseage(); + void ParseImplicitVariables(const Node& node); void ParseInputData(ExecutionTreePtr execution); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index 62e361da93..73e16024c9 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -88,7 +88,7 @@ namespace AZ { rapidjson::Value typeValue; result.Combine(StoreTypeId(typeValue, inputAnyPtr->type(), context)); - outputValue.AddMember("$type", AZStd::move(typeValue), context.GetJsonAllocator()); + outputValue.AddMember(rapidjson::StringRef(JsonSerialization::TypeIdFieldIdentifier), AZStd::move(typeValue), context.GetJsonAllocator()); } result.Combine(ContinueStoringToJsonObjectField(outputValue, "value", AZStd::any_cast(inputAnyPtr), AZStd::any_cast(defaultAnyPtr), inputAnyPtr->type(), context)); diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake index 8e7a8c0411..f980301485 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_common_files.cmake @@ -622,5 +622,4 @@ set(SKIP_UNITY_BUILD_INCLUSION_FILES Include/ScriptCanvas/Libraries/Core/FunctionCallNode.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.h Include/ScriptCanvas/Libraries/Core/FunctionCallNodeIsOutOfDate.cpp - -) \ No newline at end of file +) diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake index 0841137435..12cb1a242e 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_builder_files.cmake @@ -15,4 +15,4 @@ set(FILES Builder/ScriptCanvasBuilderWorker.h Builder/ScriptCanvasBuilderWorkerUtility.cpp Builder/ScriptCanvasFunctionBuilderWorker.cpp -) \ No newline at end of file +) From 66a935dfa49ab5b464e00786201005e717287950 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:04:06 -0700 Subject: [PATCH 09/16] Fix missing icon issue leading to failed nightly test: LYN-4926 SPEC-6982 Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp | 2 +- .../Code/Editor/View/Windows/Resources/create_graph.png | 3 +++ .../Code/Editor/View/Windows/ScriptCanvasEditorResources.qrc | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Resources/create_graph.png diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 0572c929eb..0130191d5d 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -523,7 +523,7 @@ namespace ScriptCanvasEditor // Creation Actions { m_createScriptCanvas = new QToolButton(); - m_createScriptCanvas->setIcon(QIcon(ScriptCanvas::AssetDescription::GetIconPath())); + m_createScriptCanvas->setIcon(QIcon(":/ScriptCanvasEditorResources/Resources/create_graph.png")); m_createScriptCanvas->setToolTip("Creates a new Script Canvas Graph"); QObject::connect(m_createScriptCanvas, &QToolButton::clicked, this, &MainWindow::OnFileNew); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Resources/create_graph.png b/Gems/ScriptCanvas/Code/Editor/View/Windows/Resources/create_graph.png new file mode 100644 index 0000000000..dea268cd1d --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Resources/create_graph.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f920ea2cd388c6db572344e33ccbf96f65ee6d391ae1880cfe16eff58d0da381 +size 4016 diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasEditorResources.qrc b/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasEditorResources.qrc index c9f2ff5fa3..be90d229dc 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasEditorResources.qrc +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/ScriptCanvasEditorResources.qrc @@ -12,6 +12,7 @@ Resources/capture_offline.png Resources/create_function_input.png Resources/create_function_output.png + Resources/create_graph.png Resources/CollapseAll_Icon.png Resources/edit_icon.png Resources/error_icon.png From 3948497f853f589d1922e42e0c0501ed5061750d Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:05:39 -0700 Subject: [PATCH 10/16] remove unused icon Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png diff --git a/Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png b/Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png deleted file mode 100644 index dea268cd1d..0000000000 --- a/Assets/Editor/Icons/ScriptCanvas/Viewport/ScriptCanvas.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f920ea2cd388c6db572344e33ccbf96f65ee6d391ae1880cfe16eff58d0da381 -size 4016 From fe829bfbd4c009d1d9c7348f27631a650f7d421a Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:10:17 -0700 Subject: [PATCH 11/16] Use 'missing' vs 'catastrophic' of missing $type field in user script variable json serializer Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index 73e16024c9..4a73b55646 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -33,7 +33,7 @@ namespace AZ auto typeIdMember = inputValue.FindMember(JsonSerialization::TypeIdFieldIdentifier); if (typeIdMember == inputValue.MemberEnd()) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Catastrophic, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier)); + return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Missing, AZStd::string::format("ScriptUserDataSerializer::Load failed to load the %s member", JsonSerialization::TypeIdFieldIdentifier)); } result.Combine(LoadTypeId(typeId, typeIdMember->value, context)); From 7b149e6f90799d2a693480b8a7f8a77ea89d877e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:14:05 -0700 Subject: [PATCH 12/16] remove unnecessary reporting values from user script variable json serializer Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index 4a73b55646..7738c9154d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -45,7 +45,7 @@ namespace AZ outputVariable->value = context.GetSerializeContext()->CreateAny(typeId); if (outputVariable->value.empty() || outputVariable->value.type() != typeId) { - return context.Report(JSR::Tasks::ReadField, JSR::Outcomes::Unknown, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); + return context.Report(result, "ScriptUserDataSerializer::Load failed to load a value matched the reported AZ TypeId. The C++ declaration may have been deleted or changed."); } result.Combine(ContinueLoadingFromJsonObjectField(AZStd::any_cast(&outputVariable->value), typeId, inputValue, "value", context)); From 59f4e865a4e51b3ae6fd9c6ecb0adf62f7485a33 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 18:59:11 -0700 Subject: [PATCH 13/16] whitespace and string_view fixes Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp | 2 +- .../Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp | 3 ++- .../Code/Include/ScriptCanvas/Variable/GraphVariable.cpp | 7 ++----- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index d6ee28af9e..3431165d98 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -277,7 +277,7 @@ namespace ScriptCanvasBuilder if (!resultFound) { - return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%s.", editorAssetId.ToString().c_str(), assetHint.data())); + return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%.*s.", editorAssetId.ToString().c_str(), assetHint.size(), assetHint.data())); } AZStd::vector dependentAssets; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index e971375e15..83f686305d 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -1454,7 +1454,8 @@ namespace ScriptCanvas { result.m_mostParent = outputSource; } - } while (childSequenceIndex); + } + while (childSequenceIndex); } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp index 57c40111a6..6a91f01518 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Variable/GraphVariable.cpp @@ -124,11 +124,8 @@ namespace ScriptCanvas VariableFlags::Scope scope = VariableFlags::Scope::Graph; - if ((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut) - { - scope = VariableFlags::Scope::Graph; - } - else if (exposureType & VariableFlags::Deprecated::Exposure::Exp_Input) + if (((exposureType & VariableFlags::Deprecated::Exposure::Exp_InOut) == VariableFlags::Deprecated::Exposure::Exp_InOut) + || exposureType & VariableFlags::Deprecated::Exposure::Exp_Input) { scope = VariableFlags::Scope::Graph; } From dcea6f47fa70bf1543ea86013456e27793c25730 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 30 Jun 2021 19:23:21 -0700 Subject: [PATCH 14/16] linux build fix Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index 3431165d98..7a22695935 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -277,7 +277,7 @@ namespace ScriptCanvasBuilder if (!resultFound) { - return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%.*s.", editorAssetId.ToString().c_str(), assetHint.size(), assetHint.data())); + return AZ::Failure(AZStd::string::format("LoadEditorAssetTree failed to get engine relative path from %s-%.*s.", editorAssetId.ToString().c_str(), aznumeric_cast(assetHint.size()), assetHint.data())); } AZStd::vector dependentAssets; From 8cd07c6f4b30d438f2055a004f9391ce1d4e6860 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 1 Jul 2021 05:33:59 -0700 Subject: [PATCH 15/16] update license on new files Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp | 2 +- Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h | 2 +- .../ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp | 4 ++-- .../ScriptCanvas/Serialization/ScriptUserDataSerializer.h | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp index 7a22695935..dbd36b3641 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) Contributors to the Open 3D Engine Project + * 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 * diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h index ea77b4c9b0..7cbc6c029e 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) Contributors to the Open 3D Engine Project + * 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 * diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp index 7738c9154d..158e1fb562 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.cpp @@ -1,6 +1,6 @@ /* - * Copyright (c) Contributors to the Open 3D Engine Project - * + * 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 * */ diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h index 781a3b74fe..1e627f5acb 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/ScriptUserDataSerializer.h @@ -1,6 +1,6 @@ /* - * Copyright (c) Contributors to the Open 3D Engine Project - * + * 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 * */ @@ -33,4 +33,4 @@ namespace AZ , const void* defaultValue , const Uuid& valueTypeId, JsonSerializerContext& context) override; }; -} \ No newline at end of file +} From 6b27c1d7977fa07d117c90260ed54a54f1fd19dd Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 1 Jul 2021 11:18:03 -0700 Subject: [PATCH 16/16] fix python test against editor Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py index b6ef00486b..129570f80d 100644 --- a/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py +++ b/AutomatedTesting/Gem/PythonTests/scripting/FileMenu_Default_NewAndOpen.py @@ -58,8 +58,11 @@ class TestFileMenuDefaultNewOpen: sc_main = sc.findChild(QtWidgets.QMainWindow) sc_tabs = sc_main.findChild(QtWidgets.QTabWidget, "ScriptCanvasTabs") - # 3) Trigger File->New action + # wait for the intial tab count + general.idle_wait(GENERAL_WAIT) initial_tabs_count = sc_tabs.count() + + # 3) Trigger File->New action action = pyside_utils.find_child_by_pattern( sc_main, {"objectName": "action_New_Script", "type": QtWidgets.QAction} )