diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp index 9498b67e79..1a4e7b3e80 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.cpp @@ -303,6 +303,55 @@ namespace AZ return AZ::Success(); } + AZ::Outcome LoadObjectFromStringByType(void* objectToLoad, const Uuid& classId, AZStd::string_view stream, + const JsonDeserializerSettings* settings) + { + JsonDeserializerSettings loadSettings; + AZStd::string deserializeErrors; + auto prepare = PrepareDeserializerSettings(settings, loadSettings, deserializeErrors); + if (!prepare.IsSuccess()) + { + return AZ::Failure(prepare.GetError()); + } + + auto parseResult = ReadJsonString(stream); + if (!parseResult.IsSuccess()) + { + return AZ::Failure(parseResult.GetError()); + } + + const rapidjson::Document& jsonDocument = parseResult.GetValue(); + + auto validateResult = ValidateJsonClassHeader(jsonDocument); + if (!validateResult.IsSuccess()) + { + return AZ::Failure(validateResult.GetError()); + } + + const char* className = jsonDocument.FindMember(ClassNameTag)->value.GetString(); + + // validate class name + auto classData = loadSettings.m_serializeContext->FindClassData(classId); + if (!classData) + { + return AZ::Failure(AZStd::string::format("Try to load class from Id %s", classId.ToString().c_str())); + } + + if (azstricmp(classData->m_name, className) != 0) + { + return AZ::Failure(AZStd::string::format("Try to load class %s from class %s data", classData->m_name, className)); + } + + JsonSerializationResult::ResultCode result = JsonSerialization::Load(objectToLoad, classId, jsonDocument.FindMember(ClassDataTag)->value, loadSettings); + + if (!WasLoadSuccess(result.GetOutcome()) || !deserializeErrors.empty()) + { + return AZ::Failure(deserializeErrors); + } + + return AZ::Success(); + } + AZ::Outcome LoadObjectFromStreamByType(void* objectToLoad, const Uuid& classId, IO::GenericStream& stream, const JsonDeserializerSettings* settings) { diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h index c684d0397a..89ef341aff 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonUtils.h @@ -79,6 +79,9 @@ namespace AZ AZ::Outcome ReadJsonStream(IO::GenericStream& stream); //! Load object with known class type + AZ::Outcome LoadObjectFromStringByType(void* objectToLoad, const Uuid& objectType, AZStd::string_view source, + const JsonDeserializerSettings* settings = nullptr); + AZ::Outcome LoadObjectFromStreamByType(void* objectToLoad, const Uuid& objectType, IO::GenericStream& stream, const JsonDeserializerSettings* settings = nullptr); diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp index 536a678577..f474c10532 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp @@ -6,7 +6,6 @@ * */ - #include #include #include @@ -16,20 +15,19 @@ #include #include #include - -#include +#include #include +#include #include #include #include #include +#include #include #include #include #include -#include - namespace ScriptCanvasBuilder { void Worker::Activate(const AssetHandlers& handlers) @@ -82,55 +80,18 @@ namespace ScriptCanvasBuilder m_processEditorAssetDependencies.clear(); - AZStd::unordered_multimap jobDependenciesByKey; - - auto assetFilter = [this, &jobDependenciesByKey](const AZ::Data::AssetFilterInfo& filterInfo) - { - // force load these before processing - if (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()) - { - AZ_Error("ScriptCanvas", false, "ScriptAsset Reference in a graph detected"); - } - - if (filterInfo.m_assetType == azrtti_typeid()) - { - AssetBuilderSDK::SourceFileDependency dependency; - dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid; - jobDependenciesByKey.insert({ ScriptEvents::k_builderJobKey, dependency }); - } - - if (filterInfo.m_assetType == azrtti_typeid()) - { - AssetBuilderSDK::SourceFileDependency dependency; - dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid; - jobDependenciesByKey.insert({ s_scriptCanvasProcessJobKey, dependency }); - } - - // Asset filter always returns false to prevent parsing dependencies, but makes note of the script canvas dependencies - return false; - }; - AZ::Data::Asset asset; asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom())); - if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, assetFilter) != AZ::Data::AssetHandler::LoadResult::LoadComplete) + if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, {}) != AZ::Data::AssetHandler::LoadResult::LoadComplete) { AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the asset data could not be loaded from the file", fullPath.data()); return; } - // Flush asset database events to ensure no asset references are held by closures queued on Ebuses. - AZ::Data::AssetManager::Instance().DispatchEvents(); - auto* scriptCanvasEntity = asset.Get()->GetScriptCanvasEntity(); auto* sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(scriptCanvasEntity); AZ_Assert(sourceGraph, "Graph component is missing from entity."); + AZ_Assert(sourceGraph->GetGraphData(), "GraphData is missing from entity"); struct EntityIdComparer { @@ -152,7 +113,58 @@ namespace ScriptCanvasBuilder } } - m_processEditorAssetDependencies.clear(); + AZ::SerializeContext* serializeContext{}; + AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + AZ_Assert(serializeContext, "SerializeContext is required to enumerate dependent assets in the ScriptCanvas file"); + + AZStd::unordered_multimap jobDependenciesByKey; + auto assetFilter = [this, &jobDependenciesByKey] + ( void* instancePointer + , const AZ::SerializeContext::ClassData* classData + , [[maybe_unused]] const AZ::SerializeContext::ClassElement* classElement) + { + auto azTypeId = classData->m_azRtti->GetTypeId(); + + if (azTypeId == azrtti_typeid>()) + { + const auto* subgraphAsset = reinterpret_cast*>(instancePointer); + if (subgraphAsset->GetId().IsValid()) + { + AssetBuilderSDK::SourceFileDependency dependency; + dependency.m_sourceFileDependencyUUID = subgraphAsset->GetId().m_guid; + jobDependenciesByKey.insert({ s_scriptCanvasProcessJobKey, dependency }); + this->m_processEditorAssetDependencies.push_back + ( { subgraphAsset->GetId(), azTypeId, AZ::Data::AssetLoadBehavior::PreLoad }); + } + } + else if (azTypeId == azrtti_typeid>()) + { + const auto* eventAsset = reinterpret_cast*>(instancePointer); + if (eventAsset->GetId().IsValid()) + { + AssetBuilderSDK::SourceFileDependency dependency; + dependency.m_sourceFileDependencyUUID = eventAsset->GetId().m_guid; + jobDependenciesByKey.insert({ ScriptEvents::k_builderJobKey, dependency }); + this->m_processEditorAssetDependencies.push_back + ( { eventAsset->GetId(), azTypeId, AZ::Data::AssetLoadBehavior::PreLoad }); + } + } + + // always continue, make note of the script canvas dependencies + return true; + }; + + AZ_Verify(serializeContext->EnumerateInstanceConst + ( sourceGraph->GetGraphData() + , azrtti_typeid() + , assetFilter + , {} + , AZ::SerializeContext::ENUM_ACCESS_FOR_READ + , nullptr + , nullptr), "Failed to gather dependencies from graph data"); + + // Flush asset database events to ensure no asset references are held by closures queued on Ebuses. + AZ::Data::AssetManager::Instance().DispatchEvents(); for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms) { @@ -222,7 +234,7 @@ namespace ScriptCanvasBuilder bool pathFound = false; AZStd::string relativePath; AzToolsFramework::AssetSystemRequestBus::BroadcastResult - (pathFound + ( pathFound , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath , request.m_fullPath.c_str(), relativePath); @@ -272,9 +284,6 @@ namespace ScriptCanvasBuilder assetDataStream->Open(AZStd::move(fileBuffer)); } - AZ::SerializeContext* context{}; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - AZ::Data::Asset asset; asset.Create(request.m_sourceFileUUID); if (m_editorAssetHandler->LoadAssetDataFromStream(asset, assetDataStream, nullptr) != AZ::Data::AssetHandler::LoadResult::LoadComplete) @@ -305,13 +314,6 @@ namespace ScriptCanvasBuilder } else { - // force load all dependencies into memory - for (auto& dependency : m_processEditorAssetDependencies) - { - auto depAsset = AZ::Data::AssetManager::Instance().GetAsset(dependency.m_assetId, dependency.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - depAsset.BlockUntilLoadComplete(); - } - AZ::Entity* buildEntity = asset.Get()->GetScriptCanvasEntity(); ProcessTranslationJobInput input; @@ -375,6 +377,8 @@ namespace ScriptCanvasBuilder AZ_Error(s_scriptCanvasBuilder, false, translationOutcome.GetError().c_str()); } } + + m_processEditorAssetDependencies.clear(); } AZ_TracePrintf(s_scriptCanvasBuilder, "Finish Processing Job"); diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp index 6f86b93dda..dea63ab852 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetHandler.cpp @@ -93,6 +93,49 @@ namespace ScriptCanvasEditor } } + AZ::Outcome LoadScriptCanvasDataFromJson + ( ScriptCanvas::ScriptCanvasData& dataTarget + , AZStd::string_view source + , AZ::SerializeContext& serializeContext) + { + namespace JSRU = AZ::JsonSerializationUtils; + using namespace ScriptCanvas; + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = &serializeContext; + settings.m_metadata.Create(); + + auto loadResult = JSRU::LoadObjectFromStringByType + ( &dataTarget + , azrtti_typeid() + , source + , &settings); + + if (!loadResult.IsSuccess()) + { + return loadResult; + } + + if (auto graphData = dataTarget.ModGraph()) + { + auto listeners = settings.m_metadata.Find(); + AZ_Assert(listeners, "Failed to find SerializationListeners"); + + ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->GetGraphData()->m_nodes, *listeners); + + for (auto listener : *listeners) + { + listener->OnDeserialize(); + } + } + else + { + return AZ::Failure(AZStd::string("Failed to find graph data after loading source")); + } + + return AZ::Success(); + } + AZ::Data::AssetHandler::LoadResult ScriptCanvasAssetHandler::LoadAssetData ( const AZ::Data::Asset& assetTarget , AZStd::shared_ptr streamSource @@ -110,8 +153,9 @@ namespace ScriptCanvasEditor { streamSource->Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); auto& scriptCanvasDataTarget = scriptCanvasAssetTarget->GetScriptCanvasData(); - AZStd::vector byteBuffer; + AZStd::vector byteBuffer; byteBuffer.resize_no_construct(streamSource->GetLength()); + // this duplicate stream is to allow for trying again if the JSON read fails AZ::IO::ByteContainerStream byteStreamSource(&byteBuffer); const size_t bytesRead = streamSource->Read(byteBuffer.size(), byteBuffer.data()); scriptCanvasDataTarget.m_scriptCanvasEntity.reset(nullptr); @@ -123,47 +167,45 @@ namespace ScriptCanvasEditor settings.m_serializeContext = m_serializeContext; settings.m_metadata.Create(); // attempt JSON deserialization... - if (JSRU::LoadObjectFromStreamByType - ( &scriptCanvasDataTarget - , azrtti_typeid() - , byteStreamSource - , &settings).IsSuccess()) + auto jsonResult = LoadScriptCanvasDataFromJson + ( scriptCanvasDataTarget + , AZStd::string_view{ byteBuffer.begin(), byteBuffer.size() } + , *m_serializeContext); + + if (jsonResult.IsSuccess()) { - if (auto graphData = scriptCanvasAssetTarget->GetScriptCanvasGraph() - ? scriptCanvasAssetTarget->GetScriptCanvasGraph()->GetGraphData() - : nullptr) - { - auto listeners = settings.m_metadata.Find(); - AZ_Assert(listeners, "Failed to create SerializationListeners"); - - ScriptCanvasAssetHandlerCpp::CollectNodes(graphData->m_nodes, *listeners); - - for (auto listener : *listeners) - { - listener->OnDeserialize(); - } - - return AZ::Data::AssetHandler::LoadResult::LoadComplete; - } - else - { - AZ_Warning("ScriptCanvas", false, "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JOSON"); - } + return AZ::Data::AssetHandler::LoadResult::LoadComplete; } #if defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED)//// else - {// ...if there is a failure, check if it is saved in the old format + { + // ...if there is a failure, check if it is saved in the old format byteStreamSource.Seek(0U, AZ::IO::GenericStream::ST_SEEK_BEGIN); // tolerate unknown classes in the editor. Let the asset processor warn about bad nodes... if (AZ::Utils::LoadObjectFromStreamInPlace - (byteStreamSource + ( byteStreamSource , scriptCanvasDataTarget , m_serializeContext , AZ::ObjectStream::FilterDescriptor(assetLoadFilterCB, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES))) { + AZ_Warning + ( "ScriptCanvas" + , false + , "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JSON, %s, consider converting to JSON" + " by opening it and saving it, or running the graph update tool from the editor0" + , jsonResult.GetError().c_str()); return AZ::Data::AssetHandler::LoadResult::LoadComplete; } } +#else + else + { + AZ_Warning + ( "ScriptCanvas" + , false + , "ScriptCanvasAssetHandler::LoadAssetData failed to load graph data from JSON %s" + , jsonResult.GetError().c_str()"); + } #endif//defined(OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED) } } diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp index 1899951638..f003618c03 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorGraph.cpp @@ -3467,11 +3467,12 @@ namespace ScriptCanvasEditor m_focusHelper.SetActiveGraph(GetGraphCanvasGraphId()); } - bool Graph::UpgradeGraph(const AZ::Data::Asset& asset) + bool Graph::UpgradeGraph(const AZ::Data::Asset& asset, UpgradeRequest request, bool isVerbose) { m_upgradeSM.SetAsset(asset); + m_upgradeSM.SetVerbose(isVerbose); - if (!GetVersion().IsLatest()) + if (request == UpgradeRequest::Forced || !GetVersion().IsLatest()) { m_upgradeSM.Run(Start::StateID()); return true; diff --git a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp index 9df6311a92..e87c82e186 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/GraphUpgrade.cpp @@ -79,7 +79,7 @@ namespace ScriptCanvasEditor { if (node->GetComponents().empty()) { - AZ_TracePrintf("Script Canvas", "Removing node due to missing components: %s\nVerify that all gems that this script relies on are enabled\n", node->GetName().c_str()); + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Removing node due to missing components: %s\nVerify that all gems that this script relies on are enabled\n", node->GetName().c_str()); nodesToRemove.push_back(node); } @@ -193,7 +193,7 @@ namespace ScriptCanvasEditor } else { - AZ_Warning("ScriptCanvas", false, "Could not find ScriptCanvas Node with id %llu", static_cast(scriptCanvasSourceEndpoint.GetNodeId())); + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Could not find ScriptCanvas Node with id %llu", static_cast(scriptCanvasSourceEndpoint.GetNodeId())); } AZ::EntityId graphCanvasSourceSlotId; @@ -213,7 +213,7 @@ namespace ScriptCanvasEditor if (!graphCanvasSourceSlotId.IsValid()) { - AZ_Warning("ScriptCanvas", sm->m_deletedNodes.count(scriptCanvasSourceEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasSourceEndpoint.GetNodeId().ToString().c_str()); + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), sm->m_deletedNodes.count(scriptCanvasSourceEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasSourceEndpoint.GetNodeId().ToString().c_str()); graph->DisconnectById(connectionId); continue; } @@ -229,7 +229,7 @@ namespace ScriptCanvasEditor } else { - AZ_Warning("ScriptCanvas", false, "Could not find ScriptCanvas Node with id %llu", static_cast(scriptCanvasSourceEndpoint.GetNodeId())); + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Could not find ScriptCanvas Node with id %llu", static_cast(scriptCanvasSourceEndpoint.GetNodeId())); } SlotMappingRequestBus::EventResult(graphCanvasTargetEndpoint.m_slotId, graphCanvasTargetEndpoint.GetNodeId(), &SlotMappingRequests::MapToGraphCanvasId, scriptCanvasTargetEndpoint.GetSlotId()); @@ -245,7 +245,7 @@ namespace ScriptCanvasEditor if (!graphCanvasTargetEndpoint.IsValid()) { - AZ_Warning("ScriptCanvas", sm->m_deletedNodes.count(scriptCanvasTargetEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasTargetEndpoint.GetNodeId().ToString().c_str()); + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), sm->m_deletedNodes.count(scriptCanvasTargetEndpoint.GetNodeId()) > 0, "Could not create connection(%s) for Node(%s).", connectionId.ToString().c_str(), scriptCanvasTargetEndpoint.GetNodeId().ToString().c_str()); graph->DisconnectById(connectionId); continue; } @@ -422,7 +422,7 @@ namespace ScriptCanvasEditor if (!sm->m_updateReport.IsEmpty()) { // currently, it is expected that there are no deleted old slots, those need manual correction - AZ_Error("ScriptCanvas", sm->m_updateReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required"); + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), sm->m_updateReport.m_deletedOldSlots.empty(), "Graph upgrade path: If old slots are deleted, manual upgrading is required"); UpdateConnectionStatus(*graph, sm->m_updateReport); } } @@ -511,17 +511,19 @@ namespace ScriptCanvasEditor bool saveRawTranslationOuputToFile = ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile; ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + + // save parsing status before after, just because it didn't parse after doesn't mean it didn't before graph->Parse(validationResults); ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = saveRawTranslationOuputToFile; - if (validationResults.HasResults()) + if (validationResults.HasErrors()) { + AZ::Interface::Get()->GraphNeedsManualUpgrade(sm->m_asset.GetId()); + for (auto& err : validationResults.GetEvents()) { // Register this graph as needing manual updates - AZ::Interface::Get()->GraphNeedsManualUpgrade(sm->m_asset.GetId()); - Log("%s: %s\n", err->GetIdentifier().c_str(), err->GetDescription().data()); } } @@ -678,6 +680,7 @@ namespace ScriptCanvasEditor if (m_asset != asset) { m_asset = asset; + SetDebugPrefix(asset.GetHint()); } } @@ -690,6 +693,10 @@ namespace ScriptCanvasEditor ////////////////////////////////////////////////////////////////////// // State Machine Internals + bool StateMachine::GetVerbose() const + { + return m_isVerbose; + } void StateMachine::OnSystemTick() { @@ -743,7 +750,22 @@ namespace ScriptCanvasEditor AZ::SystemTickBus::Handler::BusConnect(); } - } + void StateMachine::SetVerbose(bool isVerbose) + { + m_isVerbose = isVerbose; + } + + const AZStd::string& StateMachine::GetDebugPrefix() const + { + return m_debugPrefix; + } + + void StateMachine::SetDebugPrefix(AZStd::string_view prefix) + { + m_debugPrefix = prefix; + } + + } diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetHandler.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetHandler.h index c0af2d59ac..f29d5aa9cb 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetHandler.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetHandler.h @@ -20,6 +20,11 @@ namespace AZ namespace ScriptCanvasEditor { + AZ::Outcome LoadScriptCanvasDataFromJson + ( ScriptCanvas::ScriptCanvasData& dataTarget + , AZStd::string_view source + , AZ::SerializeContext& serializeContext); + /** * Manages editor Script Canvas graph assets. */ @@ -49,7 +54,7 @@ namespace ScriptCanvasEditor // Called by the asset database to perform actual asset save. Returns true if successful otherwise false (default - as we don't require support save). bool SaveAssetData(const AZ::Data::Asset& asset, AZ::IO::GenericStream* stream) override; bool SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream); - bool SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream , AZ::DataStream::StreamType streamType); + bool SaveAssetData(const ScriptCanvasAsset* assetData, AZ::IO::GenericStream* stream, AZ::DataStream::StreamType streamType); // Called by the asset database when an asset should be deleted. void DestroyAsset(AZ::Data::AssetPtr ptr) override; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.cpp b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.cpp new file mode 100644 index 0000000000..6da134ed6a --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.cpp @@ -0,0 +1,23 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include + +namespace ScriptCanvas +{ + Graph* ScriptCanvasData::ModGraph() + { + return AZ::EntityUtils::FindFirstDerivedComponent(m_scriptCanvasEntity.get()); + } + + const Graph* ScriptCanvasData::GetGraph() const + { + return AZ::EntityUtils::FindFirstDerivedComponent(m_scriptCanvasEntity.get()); + } +} diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h index d36b773e83..f4b02b56b6 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h @@ -28,6 +28,10 @@ namespace ScriptCanvas AZ::Entity* GetScriptCanvasEntity() const { return m_scriptCanvasEntity.get(); } + Graph* ModGraph(); + + const Graph* GetGraph() const; + AZStd::unique_ptr m_scriptCanvasEntity; private: ScriptCanvasData(const ScriptCanvasData&) = delete; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h index 1f036e22bb..4497968ffc 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/EditorScriptCanvasBus.h @@ -223,9 +223,9 @@ namespace ScriptCanvasEditor using AssetList = AZStd::list; virtual AssetList& GetAssetsToUpgrade() = 0; + virtual void ClearGraphsThatNeedUpgrade() = 0; virtual void GraphNeedsManualUpgrade(const AZ::Data::AssetId&) = 0; - virtual AZStd::vector& GetGraphsThatNeedManualUpgrade() = 0; - + virtual const AZStd::vector& GetGraphsThatNeedManualUpgrade() const = 0; virtual bool IsUpgrading() = 0; virtual void SetIsUpgrading(bool isUpgrading) = 0; }; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h index bf654a4440..cb6689091b 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorGraph.h @@ -230,7 +230,12 @@ namespace ScriptCanvasEditor ///// EditorGraphUpgradeMachine m_upgradeSM; - bool UpgradeGraph(const AZ::Data::Asset& asset); + enum UpgradeRequest + { + IfOutOfDate, + Forced + }; + bool UpgradeGraph(const AZ::Data::Asset& asset, UpgradeRequest request, bool isVerbose = true); void ConnectGraphCanvasBuses(); void DisconnectGraphCanvasBuses(); /////// diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h index df7fa0535f..89ee0f3b55 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/GraphUpgrade.h @@ -131,8 +131,20 @@ namespace ScriptCanvasEditor void OnSystemTick() override; + bool GetVerbose() const; + + void SetVerbose(bool isVerbose); + + const AZStd::string& GetDebugPrefix() const; + + void SetDebugPrefix(AZStd::string_view); + AZStd::shared_ptr m_currentState = nullptr; AZStd::vector> m_states; + + private: + bool m_isVerbose = true; + AZStd::string m_debugPrefix; }; //! This state machine will collect and share a variety of data from the EditorGraph @@ -342,19 +354,22 @@ namespace ScriptCanvasEditor int EvaluateTransition() override; }; + template void ScriptCanvasEditor::State::Log(const char* format, ...) { if (m_verbose) { - char sBuffer[1024]; + char sBuffer[2048]; va_list ArgList; va_start(ArgList, format); azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); sBuffer[sizeof(sBuffer) - 1] = '\0'; va_end(ArgList); - - AZ_TracePrintf("Script Canvas", "%s\n", sBuffer); + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data() + , "%s-%s\n" + , m_stateMachine->GetDebugPrefix().c_str() + , sBuffer); } } } diff --git a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h index 37515944c7..ba850401d6 100644 --- a/Gems/ScriptCanvas/Code/Editor/SystemComponent.h +++ b/Gems/ScriptCanvas/Code/Editor/SystemComponent.h @@ -1,3 +1,4 @@ + /* * Copyright (c) Contributors to the Open 3D Engine Project. * For complete copyright and license terms please see the LICENSE at the root of this distribution. @@ -109,6 +110,11 @@ namespace ScriptCanvasEditor //////////////////////////////////////////////////////////////////////// // IUpgradeRequests... + void ClearGraphsThatNeedUpgrade() + { + m_assetsThatNeedManualUpgrade.clear(); + } + IUpgradeRequests::AssetList& GetAssetsToUpgrade() override { return m_assetsToConvert; @@ -122,7 +128,7 @@ namespace ScriptCanvasEditor } } - AZStd::vector& GetGraphsThatNeedManualUpgrade() override + const AZStd::vector& GetGraphsThatNeedManualUpgrade() const override { return m_assetsThatNeedManualUpgrade; } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.cpp index 3d42fdad42..5e6858c993 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.cpp @@ -92,7 +92,7 @@ namespace ScriptCanvasEditor void UpgradeTool::closeEvent(QCloseEvent* event) { - m_keepEditorAlive.reset(); + // m_keepEditorAlive.reset(); DisconnectBuses(); @@ -110,7 +110,7 @@ namespace ScriptCanvasEditor { setWindowFlag(Qt::WindowCloseButtonHint, false); - m_keepEditorAlive = AZStd::make_unique(); + // m_keepEditorAlive = AZStd::make_unique(); UpdateSettings(); @@ -581,74 +581,6 @@ namespace ScriptCanvasEditor accept(); } - template - AZ::Entity* UpgradeGraph(AZ::Data::Asset& asset, UpgradeTool* upgradeTool) - { - AssetType* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of type: %s", azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return nullptr; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return nullptr; - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool isLatest = graphComponent->GetVersion().IsLatest(); - if (isLatest) - { - ++upgradeTool->SkippedGraphCount(); - - // No need to upgrade - return nullptr; - } - - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - if (graphComponent) - { - if (!graphComponent->UpgradeGraph(asset)) - { - ++upgradeTool->SkippedGraphCount(); - } - else - { - ++upgradeTool->UpgradedGraphCount(); - } - } - - return scriptCanvasEntity; - } - void UpgradeTool::SaveLog() { AZStd::string outputFileName = AZStd::string::format("@devroot@/ScriptCanvasUpgradeReport.html"); @@ -688,29 +620,9 @@ namespace ScriptCanvasEditor outputFile.Close(); } - AZ::Entity* UpgradeTool::AssetUpgradeJob(AZ::Data::Asset& asset) + AZ::Entity* UpgradeTool::AssetUpgradeJob(AZ::Data::Asset&) { - using namespace ScriptCanvasEditor; - - AZ_Assert(asset.IsReady(), "The asset must be ready by now"); - - AZStd::lock_guard myLocker(m_mutex); - - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - scriptCanvasEntity = UpgradeGraph(asset, this); - } - - if (!scriptCanvasEntity) - { - // This may happen if the graph failed or did not need to upgrade - AZ_TracePrintf("Script Canvas", "%s .. up to date!\n", asset.GetHint().c_str()); - return nullptr; - } - - // The rest will happen when we get notified that the graph is done. - return scriptCanvasEntity; + return nullptr; } void UpgradeTool::RetryMove(AZ::Data::Asset& asset, const AZStd::string& source, const AZStd::string& target) @@ -780,28 +692,6 @@ namespace ScriptCanvasEditor return false; } - ScriptCanvasEditor::EditorKeepAlive::EditorKeepAlive() - { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) - { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); - } - } - - ScriptCanvasEditor::EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) - { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } - #include } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.h index d771de4dd1..be00198457 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeTool.h @@ -38,18 +38,7 @@ namespace Ui namespace ScriptCanvasEditor { - //! Scoped utility to set and restore the "ed_KeepEditorActive" CVar in order to allow - //! the upgrade tool to work even if the editor is not in the foreground - class EditorKeepAlive - { - public: - EditorKeepAlive(); - ~EditorKeepAlive(); - - private: - int m_keepEditorActive; - ICVar* m_edKeepEditorActive; - }; + class KeepEditorAlive; //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog class UpgradeTool @@ -140,7 +129,7 @@ namespace ScriptCanvasEditor AZStd::unique_ptr m_ui; AZStd::recursive_mutex m_mutex; - AZStd::unique_ptr m_keepEditorAlive; + // AZStd::unique_ptr m_keepEditorAlive; AZStd::vector m_logs; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp index 738cfd8d22..eb182ed291 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp @@ -6,40 +6,89 @@ * */ + +#include +#include #include #include -#include #include -#include #include -#include "VersionExplorer.h" - #include #include #include +#include #include #include - #include #include - +#include +#include #include #include #include - -#include - #include #include #include - +#include #include #include -#include + +namespace VersionExplorerCpp +{ + class FileEventHandler + : public AZ::IO::FileIOEventBus::Handler + { + public: + int m_errorCode = 0; + AZStd::string m_fileName; + + FileEventHandler() + { + BusConnect(); + } + + ~FileEventHandler() + { + BusDisconnect(); + } + + void OnError(const AZ::IO::SystemFile* /*file*/, const char* fileName, int errorCode) override + { + m_errorCode = errorCode; + + if (fileName) + { + m_fileName = fileName; + } + } + }; +} namespace ScriptCanvasEditor { + EditorKeepAlive::EditorKeepAlive() + { + ISystem* system = nullptr; + CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); + + m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); + + if (m_edKeepEditorActive) + { + m_keepEditorActive = m_edKeepEditorActive->GetIVal(); + m_edKeepEditorActive->Set(1); + } + } + + EditorKeepAlive::~EditorKeepAlive() + { + if (m_edKeepEditorActive) + { + m_edKeepEditorActive->Set(m_keepEditorActive); + } + } + VersionExplorer::VersionExplorer(QWidget* parent /*= nullptr*/) : AzQtComponents::StyledDialog(parent) , m_ui(new Ui::VersionExplorer()) @@ -62,7 +111,6 @@ namespace ScriptCanvasEditor m_ui->progressBar->setVisible(false); m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); } @@ -80,14 +128,14 @@ namespace ScriptCanvasEditor { if (m_ui->verbose->isChecked()) { - char sBuffer[1024]; + char sBuffer[2048]; va_list ArgList; va_start(ArgList, format); azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); sBuffer[sizeof(sBuffer) - 1] = '\0'; va_end(ArgList); - AZ_TracePrintf("Script Canvas", "%s\n", sBuffer); + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); } } @@ -122,13 +170,13 @@ namespace ScriptCanvasEditor } else { - m_ui->tableWidget->insertRow(static_cast(m_inspectedAssets)); + m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); QTableWidgetItem* rowName = new QTableWidgetItem ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); + m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); + ++m_currentAssetRowIndex; - m_ui->tableWidget->setItem(static_cast(m_inspectedAssets), static_cast(ColumnAsset), rowName); Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_currentAssetIndex; ++m_failedAssets; ScanComplete(m_currentAsset); } @@ -136,13 +184,62 @@ namespace ScriptCanvasEditor break; case ProcessState::Upgrade: - - if (!IsUpgrading()) + { + AZStd::lock_guard lock(m_mutex); + if (m_upgradeComplete) { - OperationResult result = BackupGraph(*m_inProgressAsset); - // Make the backup - if (result == OperationResult::BackupSuccess) + ++m_upgradeAssetIndex; + m_inProgress = false; + m_ui->progressBar->setVisible(true); + m_ui->progressBar->setValue(m_upgradeAssetIndex); + + if (m_scriptCanvasEntity) { + m_scriptCanvasEntity->Deactivate(); + m_scriptCanvasEntity = nullptr; + } + + GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); + + if (!m_isUpgradingSingleGraph) + { + if (m_inProgressAsset != m_assetsToUpgrade.end()) + { + m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); + } + + if (m_inProgressAsset == m_assetsToUpgrade.end()) + { + FinalizeUpgrade(); + } + } + else + { + m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); + m_inProgress = false; + m_state = ProcessState::Inactive; + m_settingsCache.reset(); + AZ::SystemTickBus::Handler::BusDisconnect(); + AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); + } + + m_isUpgradingSingleGraph = false; + + if (m_assetsToUpgrade.empty()) + { + m_ui->upgradeAllButton->setEnabled(false); + } + + m_upgradeComplete = false; + } + + if (!IsUpgrading() && m_state == ProcessState::Upgrade) + { + AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); + // Make the backup + if (errorMessage.empty()) + { + Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); if (!items.isEmpty()) { @@ -159,12 +256,13 @@ namespace ScriptCanvasEditor } else { - GraphUpgradeComplete(*m_inProgressAsset, result); + Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); + GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); } } break; - + } default: break; } @@ -179,20 +277,28 @@ namespace ScriptCanvasEditor void VersionExplorer::OnUpgradeAll() { - AZ::Interface::Get()->SetIsUpgrading(true); - m_state = ProcessState::Upgrade; + m_settingsCache = AZStd::make_unique(); + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + ScriptCanvas::Grammar::g_printAbstractCodeModel = false; + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + AZ::Interface::Get()->SetIsUpgrading(true); + AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); m_inProgressAsset = m_assetsToUpgrade.begin(); - + AZ::Debug::TraceMessageBus::Handler::BusConnect(); AZ::SystemTickBus::Handler::BusConnect(); + m_ui->progressBar->setVisible(true); + m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); + m_ui->progressBar->setValue(m_upgradeAssetIndex); + m_keepEditorAlive = AZStd::make_unique(); } - VersionExplorer::OperationResult VersionExplorer::BackupGraph(const AZ::Data::Asset& asset) + AZStd::string VersionExplorer::BackupGraph(const AZ::Data::Asset& asset) { - bool makeBackup = m_ui->makeBackupCheckbox->isChecked(); - if (!makeBackup) + if (!m_ui->makeBackupCheckbox->isChecked()) { - return OperationResult::SkipBackup; + // considered a success + return ""; } QDateTime theTime = QDateTime::currentDateTime(); @@ -207,8 +313,8 @@ namespace ScriptCanvasEditor { if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) { - AZ_Error("Script Canvas", false, "Failed to create backup folder %s", backupPath.c_str()); - return OperationResult::BackupFail_CreateFolder; + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); + return "Failed to create backup folder"; } } @@ -243,8 +349,8 @@ namespace ScriptCanvasEditor } else { - // The file no longer exists, we'll need to skip it. - return OperationResult::BackupFail_FileNotFound; + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); + return "Failed to find source file"; } devRoot = devRootCStr; @@ -257,289 +363,290 @@ namespace ScriptCanvasEditor relativePath = relativePath.substr(1, relativePath.size() - 1); } - AZStd::string targetFilePath; - AzFramework::StringFunc::Path::Join(backupPath.c_str(), relativePath.c_str(), targetFilePath); + AzFramework::StringFunc::Path::Normalize(relativePath); + AzFramework::StringFunc::Path::Normalize(backupPath); - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Error) + AZStd::string targetFilePath = backupPath; + targetFilePath += relativePath; + + if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) { - AZ_TracePrintf("Script Canvas", "Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - } - else - { - AZ_TracePrintf("Script Canvas", "Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return OperationResult::BackupFail; + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); + return "Failed to copy source file to backup location"; } - return OperationResult::BackupSuccess; - } - - // Upgrade - - template - AZ::Entity* UpgradeGraphProcess(const AZ::Data::Asset& asset, VersionExplorer* /*versionExplorer*/) - { - AssetType* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of type: %s", azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return nullptr; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return nullptr; - } - - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - graphComponent->UpgradeGraph(asset); - } - - return scriptCanvasEntity; + Log("VersionExplorer::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); + return ""; } void VersionExplorer::UpgradeGraph(const AZ::Data::Asset& asset) { m_inProgress = true; - + m_upgradeComplete = false; + Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - - AZ::Debug::TraceMessageBus::Handler::BusConnect(); + m_scriptCanvasEntity = nullptr; UpgradeNotifications::Bus::Handler::BusConnect(); if (asset.GetType() == azrtti_typeid()) { - m_scriptCanvasEntity = UpgradeGraphProcess(asset, this); + ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); + AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" + , azrtti_typeid().template ToString().c_str()); + + if (!scriptCanvasAsset) + { + return; + } + + AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); + AZ_Assert(scriptCanvasEntity, "VersionExplorer::UpgradeGraph The Script Canvas asset must have a valid entity"); + if (!scriptCanvasEntity) + { + return; + } + + AZ::Entity* queryEntity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); + if (queryEntity) + { + if (queryEntity->GetState() == AZ::Entity::State::Active) + { + queryEntity->Deactivate(); + } + + scriptCanvasEntity = queryEntity; + } + + if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) + { + scriptCanvasEntity->Init(); + } + + if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) + { + scriptCanvasEntity->Activate(); + } + + AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); + auto graphComponent = scriptCanvasEntity->FindComponent(); + AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); + + if (graphComponent) + { + m_scriptCanvasEntity = scriptCanvasEntity; + + graphComponent->UpgradeGraph + ( asset + , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate + , m_ui->verbose->isChecked()); + } } - if (!m_scriptCanvasEntity) - { - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - return; - } + AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); } void VersionExplorer::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) { AZStd::string relativePath, fullPath; AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); + if (!fullPathFound) + { + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); + } + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); + streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) + { + this->OnSourceFileReleased(asset); + }); + streamer->QueueRequest(flushRequest); + } + + void VersionExplorer::OnSourceFileReleased(AZ::Data::Asset asset) + { + AZStd::string relativePath, fullPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); + bool fullPathFound = false; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); + m_tmpFileName.clear(); AZStd::string tmpFileName; - bool tmpFilesaved = false; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) + if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) { - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); + return; + } - if (fileStream.IsOpen()) + bool tempSavedSucceeded = false; + AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + if (fileStream.IsOpen()) + { + if (asset.GetType() == azrtti_typeid()) { - if (asset.GetType() == azrtti_typeid()) - { - tmpFilesaved = AZ::Utils::SaveObjectToStream(fileStream, AZ::DataStream::ST_XML, &asset.GetAs()->GetScriptCanvasData()); - } - - fileStream.Close(); + ScriptCanvasEditor::ScriptCanvasAssetHandler handler; + tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); } - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, &asset, fullPath, tmpFileName, tmpFilesaved](bool /*success*/, const AzToolsFramework::SourceControlFileInfo& info) - { - if (!info.IsReadOnly()) - { - if (tmpFilesaved) - { - PerformMove(asset, tmpFileName, fullPath); - } - } - else - { - if (m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - - if (tmpFilesaved) - { - PerformMove(asset, tmpFileName, fullPath); - } - } - else - { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - - if (tmpFilesaved) - { - PerformMove(asset, tmpFileName, fullPath); - } - } - - } - } - //if (!info.IsReadOnly()) - //{ - // if (tmpFilesaved) - // { - // auto normTarget = fullPath; - // AzFramework::StringFunc::Path::Normalize(normTarget); - - // auto moveResult = AZ::IO::SmartMove(tmpFileName.c_str(), normTarget.c_str()); - // if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - // { - // // Bump the slice asset up in the asset processor's queue. - // AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, fullPath.c_str()); - - // AZ::SystemTickBus::QueueFunction([this, asset]() { GraphUpgradeComplete(asset); }); - // } - // else - // { - // AZ::SystemTickBus::QueueFunction([this, asset, tmpFileName, fullPath]() { RetryMove(asset, tmpFileName, fullPath); }); - // } - - // } - //} - //else - //{ - // QWidget* mainWindow = nullptr; - // AzToolsFramework::EditorRequests::Bus::BroadcastResult(mainWindow, &AzToolsFramework::EditorRequests::GetMainWindow); - // QMessageBox::warning(mainWindow, QObject::tr("Unable to Modify Script Canvas asset"), - // QObject::tr("File is not writable."), QMessageBox::Ok, QMessageBox::Ok); - //} - }); + fileStream.Close(); } + + // attempt to remove temporary file no matter what + m_tmpFileName = tmpFileName; + if (!tempSavedSucceeded) + { + GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); + return; + } + + using SCCommandBus = AzToolsFramework::SourceControlCommandBus; + SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, + [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) + { + constexpr const size_t k_maxAttemps = 10; + + if (!info.IsReadOnly()) + { + PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); + } + else + { + if (m_overwriteAll) + { + AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); + PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); + } + else + { + int result = QMessageBox::No; + if (!m_overwriteAll) + { + QMessageBox mb(QMessageBox::Warning, + QObject::tr("Failed to Save Upgraded File"), + QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), + QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); + + result = mb.exec(); + if (result == QMessageBox::YesToAll) + { + m_overwriteAll = true; + } + } + + if (result == QMessageBox::Yes || m_overwriteAll) + { + AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); + PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); + } + } + } + }); } - void VersionExplorer::PerformMove(AZ::Data::Asset& asset, const AZStd::string& source, const AZStd::string& target) + void VersionExplorer::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target + , size_t remainingAttempts) { - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); + VersionExplorerCpp::FileEventHandler fileEventHandler; - AZ::SystemTickBus::QueueFunction([this, asset]() { GraphUpgradeComplete(asset); }); + if (remainingAttempts == 0) + { + // all attempts failed, give up + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); + GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); + } + else if (remainingAttempts == 2) + { + // before the final attempt, flush all caches + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); + streamer->SetRequestCompleteCallback(flushRequest + , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) + { + // Continue saving. + AZ::SystemTickBus::QueueFunction( + [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); + }); + streamer->QueueRequest(flushRequest); } else { - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, &asset, &source, &target]([[maybe_unused]] AZ::IO::FileRequestHandle request) + // the actual move attempt + auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); + if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) + { + m_tmpFileName.clear(); + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); + // Bump the slice asset up in the asset processor's queue. + AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); + AZ::SystemTickBus::QueueFunction([this, asset]() + { + GraphUpgradeComplete(asset, OperationResult::Success, ""); + }); + } + else + { + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); + streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) { // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target]() { RetryMove(asset, source, target); }); + AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); }); - streamer->QueueRequest(flushRequest); - - } + streamer->QueueRequest(flushRequest); + } + } } - void VersionExplorer::GraphUpgradeComplete(const AZ::Data::Asset& asset, OperationResult result /*= OperationResult::Success*/) + void VersionExplorer::GraphUpgradeComplete + ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) { - m_inProgress = false; + AZStd::lock_guard lock(m_mutex); + m_upgradeComplete = true; + m_upgradeResult = result; + m_upgradeMessage = message; + m_upgradeAsset = asset; - if (m_scriptCanvasEntity) + if (!m_tmpFileName.empty()) { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - GraphUpgradeCompleteUIUpdate(asset, result); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) + if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); } } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - AZ::SystemTickBus::Handler::BusDisconnect(); + if (m_upgradeResult == OperationResult::Failure) + { + AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); } - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } + m_tmpFileName.clear(); } - void VersionExplorer::GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset& asset, OperationResult result /*= OperationResult::Success*/) + void VersionExplorer::GraphUpgradeCompleteUIUpdate + ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) { QString text = asset.GetHint().c_str(); QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); + if (!items.isEmpty()) { for (auto* item : items) { int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); + if (label->text().compare(assetName) == 0) { m_ui->tableWidget->removeCellWidget(row, ColumnAction); @@ -554,33 +661,24 @@ namespace ScriptCanvasEditor else { doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - if (result == OperationResult::BackupFail_FileNotFound) - { - doneButton->setToolTip("The file no longer exists"); - } - else if (result == OperationResult::BackupFail_CreateFolder) - { - doneButton->setToolTip("Failed to create the backup folder"); - } - + doneButton->setToolTip(message.data()); } m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); } - - } } } void VersionExplorer::FinalizeUpgrade() { + Log("FinalizeUpgrade!"); m_inProgress = false; m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); m_ui->onlyShowOutdated->setEnabled(true); - + m_keepEditorAlive.reset(); + m_ui->progressBar->setVisible(false); // Manual correction size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); @@ -588,12 +686,16 @@ namespace ScriptCanvasEditor { m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); } + else + { + m_ui->spinner->SetText("Upgrade complete."); + } AZ::SystemTickBus::Handler::BusDisconnect(); AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); + m_settingsCache.reset(); } // Scanning @@ -604,6 +706,7 @@ namespace ScriptCanvasEditor m_assetsToInspect.clear(); m_ui->tableWidget->setRowCount(0); m_inspectedAssets = 0; + m_currentAssetRowIndex = 0; IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); DoScan(); @@ -611,9 +714,13 @@ namespace ScriptCanvasEditor void VersionExplorer::DoScan() { - AZ::SystemTickBus::Handler::BusConnect(); - m_state = ProcessState::Scan; + m_settingsCache = AZStd::make_unique(); + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + ScriptCanvas::Grammar::g_printAbstractCodeModel = false; + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + + AZ::SystemTickBus::Handler::BusConnect(); AZ::Debug::TraceMessageBus::Handler::BusConnect(); if (!m_assetsToInspect.empty()) @@ -621,8 +728,9 @@ namespace ScriptCanvasEditor m_discoveredAssets = m_assetsToInspect.size(); m_failedAssets = 0; m_inspectedAssets = 0; - + m_currentAssetRowIndex = 0; m_ui->progressFrame->setVisible(true); + m_ui->progressBar->setVisible(true); m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); m_ui->progressBar->setValue(0); @@ -634,21 +742,20 @@ namespace ScriptCanvasEditor m_ui->onlyShowOutdated->setEnabled(false); m_inspectingAsset = m_assetsToInspect.begin(); + m_keepEditorAlive = AZStd::make_unique(); } } void VersionExplorer::BackupComplete() { - m_currentAssetIndex = 0; + m_currentAssetRowIndex = 0; m_ui->progressBar->setValue(0); - DoScan(); } void VersionExplorer::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) { Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; if (asset.GetType() == azrtti_typeid()) { @@ -668,18 +775,19 @@ namespace ScriptCanvasEditor bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); bool forceUpgrade = m_ui->forceUpgrade->isChecked(); + ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - if (!forceUpgrade && onlyShowOutdatedGraphs && graphComponent->GetVersion().IsLatest()) + + if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) { - ++m_currentAssetIndex; ScanComplete(asset); Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); return; } - m_ui->tableWidget->insertRow(static_cast(m_inspectedAssets)); + m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_inspectedAssets), static_cast(ColumnAsset), rowName); + m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) { @@ -703,14 +811,10 @@ namespace ScriptCanvasEditor }); - m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnStatus), spinner); + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); } - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); @@ -722,22 +826,22 @@ namespace ScriptCanvasEditor AZStd::string watchFolder; QByteArray assetNameUtf8 = asset.GetHint().c_str(); AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - if (!result) - { - AZ_Error("AssetProvider", false, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - } + + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); + + QToolButton* browseButton = new QToolButton(this); + browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); + browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { AzQtComponents::ShowFileOnDesktop(absolutePath); }); - m_ui->tableWidget->setCellWidget(static_cast(m_inspectedAssets), static_cast(ColumnBrowse), browseButton); - - ++m_inspectedAssets; - ++m_currentAssetIndex; + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); ScanComplete(asset); + ++m_inspectedAssets; + ++m_currentAssetRowIndex; } void VersionExplorer::UpgradeSingle @@ -752,7 +856,7 @@ namespace ScriptCanvasEditor { asset.BlockUntilLoadComplete(); - if (!asset.IsReady()) + if (asset.IsReady()) { AZ::Interface::Get()->SetIsUpgrading(true); m_isUpgradingSingleGraph = true; @@ -777,7 +881,7 @@ namespace ScriptCanvasEditor { Log("ScanComplete: %s", asset.GetHint().c_str()); m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetIndex)); + m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); m_ui->scanButton->setEnabled(true); m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); @@ -818,8 +922,8 @@ namespace ScriptCanvasEditor } else { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets)); + spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" + , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); } @@ -836,6 +940,7 @@ namespace ScriptCanvasEditor UpgradeNotifications::Bus::Handler::BusDisconnect(); m_keepEditorAlive.reset(); + m_settingsCache.reset(); m_state = ProcessState::Inactive; } @@ -866,8 +971,13 @@ namespace ScriptCanvasEditor } - void VersionExplorer::CaptureLogFromTraceBus(const char* /*window*/, const char* message) + bool VersionExplorer::CaptureLogFromTraceBus(const char* window, const char* message) { + if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) + { + return true; + } + AZStd::string msg = message; if (msg.ends_with("\n")) { @@ -875,64 +985,30 @@ namespace ScriptCanvasEditor } m_logs.push_back(msg); + return m_ui->updateReportingOnly->isChecked(); } bool VersionExplorer::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) { AZStd::string msg = AZStd::string::format("(Error): %s", message); - CaptureLogFromTraceBus(window, msg.c_str()); - - return false; + return CaptureLogFromTraceBus(window, msg.c_str()); } bool VersionExplorer::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) { AZStd::string msg = AZStd::string::format("(Warning): %s", message); - CaptureLogFromTraceBus(window, msg.c_str()); - - return false; + return CaptureLogFromTraceBus(window, msg.c_str()); } bool VersionExplorer::OnException(const char* message) { AZStd::string msg = AZStd::string::format("(Exception): %s", message); - CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - - return false; + return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); } bool VersionExplorer::OnPrintf(const char* window, const char* message) { - CaptureLogFromTraceBus(window, message); - return false; - } - - void VersionExplorer::RetryMove(const AZ::Data::Asset& asset, const AZStd::string& source, const AZStd::string& target) - { - auto normTarget = target; - AzFramework::StringFunc::Path::Normalize(normTarget); - auto moveResult = AZ::IO::SmartMove(source.c_str(), normTarget.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - - AZ::SystemTickBus::QueueFunction([this, asset]() { GraphUpgradeComplete(asset); }); - } - else - { - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, &asset, &source, &target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target]() { RetryMove(asset, source, target); }); - }); - streamer->QueueRequest(flushRequest); - - - //AZ::SystemTickBus::QueueFunction([this, asset, source, target]() { RetryMove(asset, source, target); }); - } + return CaptureLogFromTraceBus(window, message); } void VersionExplorer::closeEvent(QCloseEvent* event) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h index 266a42e2e6..acb28a7dba 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h @@ -20,11 +20,11 @@ AZ_POP_DISABLE_WARNING #include #include +#include #include #include #include -#include "UpgradeTool.h" #endif class QPushButton; @@ -41,6 +41,19 @@ namespace AzQtComponents namespace ScriptCanvasEditor { + //! Scoped utility to set and restore the "ed_KeepEditorActive" CVar in order to allow + //! the upgrade tool to work even if the editor is not in the foreground + class EditorKeepAlive + { + public: + EditorKeepAlive(); + ~EditorKeepAlive(); + + private: + int m_keepEditorActive; + ICVar* m_edKeepEditorActive; + }; + //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog class VersionExplorer : public AzQtComponents::StyledDialog @@ -71,14 +84,10 @@ namespace ScriptCanvasEditor Inactive, Backup, Scan, - Upgrade + Upgrade, }; ProcessState m_state = ProcessState::Inactive; - bool DoBackup(); - void BackupAsset(const AZ::Data::AssetInfo& assetInfo); - void BackupComplete(); - void DoScan(); void ScanComplete(const AZ::Data::Asset&); @@ -97,24 +106,21 @@ namespace ScriptCanvasEditor bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; // - void CaptureLogFromTraceBus(const char* window, const char* message); + bool CaptureLogFromTraceBus(const char* window, const char* message); enum class OperationResult { Success, - SkipBackup, - BackupSuccess, - BackupFail, - BackupFail_CreateFolder, - BackupFail_FileNotFound + Failure, }; - void GraphUpgradeComplete(const AZ::Data::Asset&, OperationResult result = OperationResult::Success); + void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); bool IsUpgrading() const; bool m_inProgress = false; - size_t m_currentAssetIndex = 0; + // scan fields + size_t m_currentAssetRowIndex = 0; size_t m_inspectedAssets = 0; size_t m_failedAssets = 0; size_t m_discoveredAssets = 0; @@ -129,7 +135,16 @@ namespace ScriptCanvasEditor AZStd::unique_ptr m_ui; + AZStd::unique_ptr m_settingsCache; + + // upgrade fields AZStd::recursive_mutex m_mutex; + bool m_upgradeComplete = false; + AZ::Data::Asset m_upgradeAsset; + int m_upgradeAssetIndex = 0; + OperationResult m_upgradeResult; + AZStd::string m_upgradeMessage; + AZStd::string m_tmpFileName; AZStd::unique_ptr m_keepEditorAlive; @@ -146,18 +161,19 @@ namespace ScriptCanvasEditor void FinalizeUpgrade(); void FinalizeScan(); - OperationResult BackupGraph(const AZ::Data::Asset&); + void BackupComplete(); + AZStd::string BackupGraph(const AZ::Data::Asset&); void UpgradeGraph(const AZ::Data::Asset&); - void RetryMove(const AZ::Data::Asset& asset, const AZStd::string& source, const AZStd::string& target); - - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset& asset, OperationResult result = OperationResult::Success); + void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; + void OnSourceFileReleased(AZ::Data::Asset asset); + void closeEvent(QCloseEvent* event) override; bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset& asset, const AZStd::string& source, const AZStd::string& target); + void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); void Log(const char* format, ...); }; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.ui b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.ui index 3e2604dd99..0cd67bcf22 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.ui +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.ui @@ -9,8 +9,8 @@ 0 0 - 747 - 687 + 1363 + 770 @@ -261,10 +261,10 @@ 0 - - Qt::ScrollBarAlwaysOn - - + + Qt::ScrollBarAlwaysOn + + true @@ -273,6 +273,16 @@ + + + + Backup before upgrade + + + true + + + @@ -311,36 +321,16 @@ - - + + - Only show outdated graphs + Verbose - true + false - - - - Force Upgrade - - - false - - - - - - - Verbose - - - false - - - @@ -354,16 +344,36 @@ - - + + - Backup before upgrade + Only show outdated graphs true + + + + Force Upgrade + + + false + + + + + + + Update Reporting Only + + + true + + + diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp index 1986eb653e..9b2d0e4982 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp @@ -135,8 +135,19 @@ namespace ScriptCanvas if (AZ::SerializeContext* serializeContext = azrtti_cast(context)) { serializeContext->Class() + ->Version(2, [](AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) + { + if (classElement.GetVersion() < 2) + { + FileVersion fileVersion = ScriptCanvas::FileVersion::Initial; + classElement.AddElementWithData(context, "_fileVersion", fileVersion); + } + + return true; + }) ->Field("_grammarVersion", &VersionData::grammarVersion) ->Field("_runtimeVersion", &VersionData::runtimeVersion) + ->Field("_fileVersion", &VersionData::fileVersion) ; } } @@ -152,6 +163,7 @@ namespace ScriptCanvas { grammarVersion = GrammarVersion::Current; runtimeVersion = RuntimeVersion::Current; + fileVersion = FileVersion::Current; } void ReflectEventTypeOnDemand(const AZ::TypeId& typeId, AZStd::string_view name, AZ::IRttiHelper* rttiHelper) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index 170e4c5acb..0e64c19dcb 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -57,6 +57,8 @@ namespace ScriptCanvas constexpr const char* k_OnVariableWriteEventName = "OnVariableValueChanged"; constexpr const char* k_OnVariableWriteEbusName = "VariableNotification"; + constexpr const AZStd::string_view k_VersionExplorerWindow = "VersionExplorerWindow"; + class Node; class Edge; @@ -69,6 +71,13 @@ namespace ScriptCanvas using NodePtrList = AZStd::vector; using NodePtrConstList = AZStd::vector; + enum class PropertyStatus : AZ::u8 + { + Getter, + None, + Setter, + }; + enum class GrammarVersion : int { Initial = -1, @@ -87,11 +96,13 @@ namespace ScriptCanvas Current, }; - enum class PropertyStatus : AZ::u8 + enum class FileVersion : int { - Getter, - None, - Setter, + Initial = -1, + JSON = 0, + + // add new entries above + Current, }; struct VersionData @@ -104,10 +115,13 @@ namespace ScriptCanvas GrammarVersion grammarVersion = GrammarVersion::Initial; RuntimeVersion runtimeVersion = RuntimeVersion::Initial; + FileVersion fileVersion = FileVersion::Initial; bool operator == (const VersionData& rhs) const { - return grammarVersion == rhs.grammarVersion && runtimeVersion == rhs.runtimeVersion; + return grammarVersion == rhs.grammarVersion + && runtimeVersion == rhs.runtimeVersion + && fileVersion == rhs.fileVersion; } bool IsLatest() const diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp index 4878dfdc6c..14f7a926b1 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp @@ -17,5 +17,23 @@ namespace ScriptCanvas 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."); + + SettingsCache::SettingsCache() + { + m_disableParseOnGraphValidation = g_disableParseOnGraphValidation; + m_printAbstractCodeModel = g_printAbstractCodeModel; + m_printAbstractCodeModelAtPrefabTime = g_printAbstractCodeModelAtPrefabTime; + m_saveRawTranslationOuputToFile = g_saveRawTranslationOuputToFile; + m_saveRawTranslationOuputToFileAtPrefabTime = g_saveRawTranslationOuputToFileAtPrefabTime; + } + + SettingsCache::~SettingsCache() + { + g_disableParseOnGraphValidation = m_disableParseOnGraphValidation; + g_printAbstractCodeModel = m_printAbstractCodeModel; + g_printAbstractCodeModelAtPrefabTime = m_printAbstractCodeModelAtPrefabTime; + g_saveRawTranslationOuputToFile = m_saveRawTranslationOuputToFile; + g_saveRawTranslationOuputToFileAtPrefabTime = m_saveRawTranslationOuputToFileAtPrefabTime; + } } } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h index 16befe79b0..a6ce31d6e7 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h @@ -248,6 +248,22 @@ namespace ScriptCanvas AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFile); AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFileAtPrefabTime); + class SettingsCache + { + public: + AZ_CLASS_ALLOCATOR(SettingsCache, AZ::SystemAllocator, 0); + + SettingsCache(); + ~SettingsCache(); + + private: + bool m_disableParseOnGraphValidation; + bool m_printAbstractCodeModel; + bool m_printAbstractCodeModelAtPrefabTime; + bool m_saveRawTranslationOuputToFile; + bool m_saveRawTranslationOuputToFileAtPrefabTime; + }; + struct DependencyInfo { AZ::Data::AssetId assetId; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp index eb1ee501a9..793224fd86 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/Method.cpp @@ -681,6 +681,13 @@ namespace ScriptCanvas outType = eventType; return true; } + + AZ_Warning("Script Canvas" + , !m_warnOnMissingFunction + , "Could not find event: %s, in bus: %s, anywhere in BehaviorContext" + , methodName.c_str() + , m_className.c_str()); + return false; } break; @@ -693,6 +700,12 @@ namespace ScriptCanvas outType = EventType::Count; return true; } + + AZ_Warning("Script Canvas" + , !m_warnOnMissingFunction + , "Could not find free method: %s anywhere in BehaviorContext" + , methodName.c_str()); + return false; } break; @@ -709,15 +722,27 @@ namespace ScriptCanvas outType = EventType::Count; return true; } + + AZ_Warning("Script Canvas" + , !m_warnOnMissingFunction + , "Could not find method or property: %s in class %s: , anywhere in BehaviorContext" + , methodName.c_str() + , m_className.c_str()); + return false; } break; - default: - AZ_Warning("Script Canvas", !m_warnOnMissingFunction, "unsupported method type in method"); + default: break; } } + AZ_Warning("Script Canvas" + , !m_warnOnMissingFunction + , "Could not find overloaded method: %s, class or event name: %s, anywhere in BehaviorContext" + , methodName.c_str() + , m_className.c_str()); + return false; } diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp index b874077834..5a2eb80187 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.cpp @@ -353,7 +353,7 @@ namespace ScriptCanvas AZStd::optional ReceiveScriptEvent::GetEventIndex(AZStd::string eventName) const { - return m_handler->GetFunctionIndex(eventName.c_str());; + return m_handler ? AZStd::optional(m_handler->GetFunctionIndex(eventName.c_str())) : AZStd::nullopt; } AZStd::vector ReceiveScriptEvent::GetEventSlotIds() const @@ -556,29 +556,6 @@ namespace ScriptCanvas return true; } - bool ReceiveScriptEvent::SetupHandler() - { - if (!m_handler) - { - if (!m_asset.IsReady() && m_scriptEventAssetId.IsValid()) - { - m_asset = AZ::Data::AssetManager::Instance().GetAsset(m_scriptEventAssetId, AZ::Data::AssetLoadBehavior::PreLoad); - m_asset.BlockUntilLoadComplete(); - CreateHandler(m_asset); - CreateEbus(); - } - - if (!m_handler) - { - AZStd::string error = AZStd::string::format("Script Event receiver node was not initialized (%s)!", m_definition.GetName().c_str()); - SCRIPTCANVAS_REPORT_ERROR((*this), error.c_str()); - return false; - } - } - - return true; - } - bool ReceiveScriptEvent::IsOutOfDate(const VersionData& graphVersion) const { AZ_UNUSED(graphVersion); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h index f2bdd98b2b..0f8d673629 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Libraries/Core/ReceiveScriptEvent.h @@ -88,7 +88,6 @@ namespace ScriptCanvas private: bool CreateEbus(); - bool SetupHandler(); AZ::BehaviorEBusHandler* m_handler = nullptr; AZ::BehaviorEBus* m_ebus = nullptr; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp index 37d6e2c35f..37fd3b14d6 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Serialization/DatumSerializer.cpp @@ -125,7 +125,7 @@ namespace AZ { listeners->push_back(outputDatum); } - + return context.Report(result, result.GetProcessing() != JSR::Processing::Halted ? "DatumSerializer Load finished loading Datum" : "DatumSerializer Load failed to load Datum"); @@ -145,13 +145,13 @@ namespace AZ auto inputScriptDataPtr = reinterpret_cast(inputValue); auto defaultScriptDataPtr = reinterpret_cast(defaultValue); - + if (defaultScriptDataPtr) { if (*inputScriptDataPtr == *defaultScriptDataPtr) { return context.Report - ( JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum"); + (JSR::Tasks::WriteValue, JSR::Outcomes::DefaultsUsed, "DatumSerializer Store used defaults for Datum"); } } diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake index 1b9f07594a..52b1cc4772 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake @@ -21,6 +21,8 @@ set(FILES Editor/Assets/ScriptCanvasAssetHelpers.h Editor/Assets/ScriptCanvasAssetHelpers.cpp Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h + Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.h + Editor/Include/ScriptCanvas/Assets/ScriptCanvasBaseAssetData.cpp Editor/Include/ScriptCanvas/Assets/ScriptCanvasAsset.h Editor/Assets/ScriptCanvasAsset.cpp Editor/Include/ScriptCanvas/Assets/ScriptCanvasAssetBus.h diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputError.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputError.scriptcanvas deleted file mode 100644 index b4f2ad14fa..0000000000 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputError.scriptcanvas +++ /dev/null @@ -1,1396 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputErrorSource.scriptcanvas_fn b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputErrorSource.scriptcanvas_fn deleted file mode 100644 index 145019ed18..0000000000 --- a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_SimultaneousDataInputErrorSource.scriptcanvas_fn +++ /dev/null @@ -1,1331 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 29360912d8..499bb84c2d 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -77,6 +77,7 @@ ly_add_target( # By default, the above module is used only in tools: ly_create_alias(NAME ScriptCanvasTesting.Tools NAMESPACE Gem TARGETS Gem::ScriptCanvasTesting.Editor) +ly_create_alias(NAME ScriptCanvasTesting.Builders NAMESPACE Gem TARGETS Gem::ScriptCanvasTesting.Editor) ################################################################################ # Tests diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index c2fa59b037..00705bfbaa 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -367,11 +367,6 @@ TEST_F(ScriptCanvasTestFixture, InterpretedMultipleOutDataFlowParseError) ExpectParseError("LY_SC_UnitTest_MultipleOutDataFlowParseError"); } -TEST_F(ScriptCanvasTestFixture, InterpretedSimultaneousDataInputError) -{ - ExpectParseError("LY_SC_UnitTest_SimultaneousDataInputError"); -} - TEST_F(ScriptCanvasTestFixture, InterpretedAnyAsTailNoOp) { RunUnitTestGraph("LY_SC_UnitTest_AnyAsTailNoOp");