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] 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