From 04fe1d52435d74d341afdd3d6f738706a25350e3 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 22 Nov 2021 11:03:37 -0800 Subject: [PATCH] File state change include external delete detection Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Asset/EditorAssetSystemComponent.cpp | 50 ++-- .../Builder/ScriptCanvasBuilderWorker.cpp | 51 ---- .../Assets/ScriptCanvasAssetTracker.cpp | 44 --- .../Editor/Assets/ScriptCanvasAssetTracker.h | 6 +- .../Assets/ScriptCanvasAssetTrackerBus.h | 1 + .../ScriptCanvasAssetTrackerDefinitions.h | 12 - .../Editor/Assets/ScriptCanvasMemoryAsset.h | 2 + .../EditorScriptCanvasComponent.cpp | 2 +- .../Code/Editor/Components/EditorUtils.cpp | 53 ++-- .../FunctionNodeDescriptorComponent.cpp | 3 +- .../Include/ScriptCanvas/Bus/RequestBus.h | 16 +- .../Components/EditorScriptCanvasComponent.h | 8 +- .../ScriptCanvas/Components/EditorUtils.h | 3 + .../Code/Editor/View/Widgets/GraphTabBar.cpp | 9 +- .../Code/Editor/View/Widgets/GraphTabBar.h | 6 +- .../LoggingPanel/LoggingWindowSession.cpp | 9 +- .../UnitTestPanel/UnitTestDockWidget.cpp | 5 +- .../Code/Editor/View/Windows/MainWindow.cpp | 261 +++++++----------- .../Code/Editor/View/Windows/MainWindow.h | 27 +- .../Tools/UpgradeTool/UpgradeHelper.cpp | 2 +- .../Code/Include/ScriptCanvas/Core/Core.cpp | 8 +- .../Code/Include/ScriptCanvas/Core/Core.h | 2 - 22 files changed, 218 insertions(+), 362 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp index 3515eaf34f..1f614a5a87 100644 --- a/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp +++ b/Gems/ScriptCanvas/Code/Asset/EditorAssetSystemComponent.cpp @@ -107,11 +107,15 @@ namespace ScriptCanvasEditor return ScriptCanvasBuilder::CreateLuaAsset(editAsset, graphPathForRawLuaFile); } - void EditorAssetSystemComponent::AddSourceFileOpeners([[maybe_unused]] const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUuid, [[maybe_unused]] AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) + void EditorAssetSystemComponent::AddSourceFileOpeners + ( [[maybe_unused]] const char* fullSourceFileName + , const AZ::Uuid& sourceUuid + , AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) { using namespace AzToolsFramework; using namespace AzToolsFramework::AssetBrowser; - if (const SourceAssetBrowserEntry* source = SourceAssetBrowserEntry::GetSourceByUuid(sourceUuid)) // get the full details of the source file based on its UUID. + // get the full details of the source file based on its UUID. + if (const SourceAssetBrowserEntry* source = SourceAssetBrowserEntry::GetSourceByUuid(sourceUuid)) { if (!HandlesSource(source)) { @@ -123,23 +127,31 @@ namespace ScriptCanvasEditor // has no UUID / Not a source file. return; } - // You can push back any number of "Openers" - choose a unique identifier, and icon, and then a lambda which will be activated if the user chooses to open it with your opener: - // #sc_editor_asset - // openers.push_back({ "ScriptCanvas_Editor_Asset_Edit", "Script Canvas Editor...", QIcon(), -// [](const char*, const AZ::Uuid& scSourceUuid) -// { -// AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas); -// AZ::Data::AssetId sourceAssetId(scSourceUuid, 0); -// -// auto& assetManager = AZ::Data::AssetManager::Instance(); -// AZ::Data::Asset scriptCanvasAsset = assetManager.GetAsset(sourceAssetId, azrtti_typeid(), AZ::Data::AssetLoadBehavior::Default); -// AZ::Outcome openOutcome = AZ::Failure(AZStd::string()); -// GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, scriptCanvasAsset.GetId(), -1); -// if (!openOutcome) -// { -// AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data()); -// } -// } }); + // You can push back any number of "Openers" - choose a unique identifier, and icon, + // and then a lambda which will be activated if the user chooses to open it with your opener: + + openers.push_back({ "ScriptCanvas_Editor_Asset_Edit", "Script Canvas Editor..." + , QIcon(ScriptCanvasAssetDescription().GetIconPathImpl()), + [](const char*, const AZ::Uuid& scSourceUuid) + { + AzToolsFramework::OpenViewPane(LyViewPane::ScriptCanvas); + + if (auto sourceHandle = CompleteDescription(SourceHandle(nullptr, scSourceUuid, {}))) + { + AZ::Outcome openOutcome = AZ::Failure(AZStd::string()); + GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset + , *sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1); + if (!openOutcome) + { + AZ_Warning("ScriptCanvas", openOutcome, "%s", openOutcome.GetError().data()); + } + } + else + { + AZ_Warning("ScriptCanvas", false + , "Unabled to find full path for Source UUid %s", scSourceUuid.ToString().c_str()); + } + }}); } } diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp index faad1871ac..bf98e62b71 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp @@ -60,57 +60,6 @@ namespace ScriptCanvasBuilder graphData = sourceGraph->GetGraphDataConst(); } -#if defined(EDITOR_ASSET_SUPPORT_ENABLED) - if (graphData == nullptr) - { - if (!m_editorAssetHandler) - { - AZ_Error(s_scriptCanvasBuilder, false, R"(CreateJobs for %s failed because the ScriptCanvas Editor Asset handler is missing.)", fullPath.data()); - } - - AZStd::shared_ptr assetDataStream = AZStd::make_shared(); - - AZ::IO::FileIOStream stream(fullPath.c_str(), AZ::IO::OpenMode::ModeRead); - if (!AZ::IO::RetryOpenStream(stream)) - { - AZ_Warning(s_scriptCanvasBuilder, false, "CreateJobs for \"%s\" failed because the source file could not be opened.", fullPath.data()); - return; - } - - // Read the asset into a memory buffer, then hand ownership of the buffer to assetDataStream - { - AZ::IO::FileIOStream ioStream; - if (!ioStream.Open(fullPath.data(), AZ::IO::OpenMode::ModeRead)) - { - 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()) - { - AZ_Warning(s_scriptCanvasBuilder, false, AZStd::string::format("File failed to read completely: %s", fullPath.data()).c_str()); - return; - } - - assetDataStream->Open(AZStd::move(fileBuffer)); - } - - m_processEditorAssetDependencies.clear(); - - asset.Create(AZ::Data::AssetId(AZ::Uuid::CreateRandom())); - 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; - } - - sourceGraph = AZ::EntityUtils::FindFirstDerivedComponent(asset.Get()->GetScriptCanvasEntity()); - graphData = sourceGraph->GetGraphDataConst(); - } -#endif - AZ_Assert(sourceGraph, "Graph component is missing from entity."); AZ_Assert(graphData, "GraphData is missing from entity"); diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.cpp b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.cpp index 513dc6afe5..5ec620a907 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.cpp @@ -541,48 +541,4 @@ namespace ScriptCanvasEditor return AZ::EntityId(); } - void AssetTracker::OnAssetReady(const ScriptCanvasMemoryAsset* asset) - { - AZ::Data::AssetId assetId = CheckAssetId(asset->GetId()); - - auto assetInUseIter = m_assetsInUse.find(assetId); - if (assetInUseIter != m_assetsInUse.end()) - { - AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetReady, assetInUseIter->second); - } - } - - void AssetTracker::OnAssetReloaded(const ScriptCanvasMemoryAsset* asset) - { - AZ::Data::AssetId assetId = CheckAssetId(asset->GetId()); - - auto assetInUseIter = m_assetsInUse.find(assetId); - if (assetInUseIter != m_assetsInUse.end()) - { - AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetReloaded, assetInUseIter->second); - } - } - - void AssetTracker::OnAssetSaved(const ScriptCanvasMemoryAsset* asset, bool isSuccessful) - { - AZ::Data::AssetId assetId = CheckAssetId(asset->GetId()); - - auto assetInUseIter = m_assetsInUse.find(assetId); - if (assetInUseIter != m_assetsInUse.end()) - { - AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetSaved, assetInUseIter->second, isSuccessful); - } - } - - void AssetTracker::OnAssetError(const ScriptCanvasMemoryAsset* asset) - { - AZ::Data::AssetId assetId = CheckAssetId(asset->GetId()); - - auto assetInUseIter = m_assetsInUse.find(assetId); - if (assetInUseIter != m_assetsInUse.end()) - { - AssetTrackerNotificationBus::Broadcast(&AssetTrackerNotifications::OnAssetError, assetInUseIter->second); - } - } - } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.h b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.h index b55e5c06c8..247aba3b94 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.h +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTracker.h @@ -16,6 +16,7 @@ #include #include +#include namespace ScriptCanvasEditor @@ -122,10 +123,5 @@ namespace ScriptCanvasEditor // Invoked when an asset is loaded from file and becomes ready Callbacks::OnAssetReadyCallback m_onAssetReadyCallback; - // Internal::MemoryAssetNotificationBus - void OnAssetReady(const ScriptCanvasMemoryAsset* asset) override; - void OnAssetReloaded(const ScriptCanvasMemoryAsset* asset) override; - void OnAssetSaved(const ScriptCanvasMemoryAsset* asset, bool isSuccessful) override; - void OnAssetError(const ScriptCanvasMemoryAsset* asset) override; }; } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerBus.h b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerBus.h index 3fecb0aac9..fd50b40768 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerBus.h +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerBus.h @@ -17,6 +17,7 @@ #include #include +#include class QWidget; diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h index 29f88b33c8..73507112c2 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasAssetTrackerDefinitions.h @@ -24,17 +24,5 @@ namespace ScriptCanvasEditor using OnAssetCreatedCallback = OnAssetReadyCallback; } - namespace Tracker - { - enum class ScriptCanvasFileState : AZ::s32 - { - NEW, - MODIFIED, - UNMODIFIED, - // #sc_editor_asset restore this - SOURCE_REMOVED, - INVALID = -1 - }; - } } diff --git a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasMemoryAsset.h b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasMemoryAsset.h index d7f6ae87b6..6eecc5e04f 100644 --- a/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasMemoryAsset.h +++ b/Gems/ScriptCanvas/Code/Editor/Assets/ScriptCanvasMemoryAsset.h @@ -29,6 +29,8 @@ #include #include +#include + namespace ScriptCanvasEditor { diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp index 27b03874ae..b4d8593a87 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorScriptCanvasComponent.cpp @@ -235,7 +235,7 @@ namespace ScriptCanvasEditor if (m_sourceHandle.IsValid()) { - GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_sourceHandle, -1); + GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, m_sourceHandle, Tracker::ScriptCanvasFileState::UNMODIFIED, -1); if (!openOutcome) { diff --git a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp index 9b83acefa5..adf5035dbd 100644 --- a/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp +++ b/Gems/ScriptCanvas/Code/Editor/Components/EditorUtils.cpp @@ -35,36 +35,45 @@ namespace ScriptCanvasEditor { if (source.IsValidDescription()) { - return source.Describe(); + return source; } - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - - if (!source.Id().IsNull()) + AzToolsFramework::AssetSystemRequestBus::Events* assetSystem = AzToolsFramework::AssetSystemRequestBus::FindFirstHandler(); + if (assetSystem) { - AzToolsFramework::AssetSystemRequestBus::BroadcastResult - ( sourceInfoFound - , &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourceUUID, source.Id(), assetInfo, watchFolder); + AZStd::string watchFolder; + AZ::Data::AssetInfo assetInfo; - if (sourceInfoFound && !assetInfo.m_relativePath.empty()) + if (!source.Id().IsNull()) { - return SourceHandle(nullptr, assetInfo.m_assetId.m_guid, assetInfo.m_relativePath); + if (assetSystem->GetSourceInfoBySourceUUID(source.Id(), assetInfo, watchFolder)) + { + AZ::IO::Path watchPath(watchFolder); + AZ::IO::Path assetInfoPath(assetInfo.m_relativePath); + SourceHandle fullPathHandle(nullptr, assetInfo.m_assetId.m_guid, watchPath / assetInfoPath); + + if (assetSystem->GetSourceInfoBySourcePath(fullPathHandle.Path().c_str(), assetInfo, watchFolder) && assetInfo.m_assetId.IsValid()) + { + if (assetInfo.m_assetId.m_guid != source.Id()) + { + AZ_TracePrintf("ScriptCanvas", "This is what I don't get"); + } + + auto path = fullPathHandle.Path(); + return SourceHandle(source, assetInfo.m_assetId.m_guid, path.MakePreferred()); + } + } + } + + if (!source.Path().empty()) + { + if (assetSystem->GetSourceInfoBySourcePath(source.Path().c_str(), assetInfo, watchFolder) && assetInfo.m_assetId.IsValid()) + { + return SourceHandle(source, assetInfo.m_assetId.m_guid, source.Path()); + } } } - if (!source.Path().empty()) - { - AzToolsFramework::AssetSystemRequestBus::BroadcastResult - ( sourceInfoFound - , &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, source.Path().c_str(), assetInfo, watchFolder); - - if (sourceInfoFound && assetInfo.m_assetId.IsValid()) - { - return SourceHandle(nullptr, assetInfo.m_assetId.m_guid, assetInfo.m_relativePath); - } - } return AZStd::nullopt; } diff --git a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/NodeDescriptors/FunctionNodeDescriptorComponent.cpp b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/NodeDescriptors/FunctionNodeDescriptorComponent.cpp index f649bb9f7d..f80c6dde21 100644 --- a/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/NodeDescriptors/FunctionNodeDescriptorComponent.cpp +++ b/Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/NodeDescriptors/FunctionNodeDescriptorComponent.cpp @@ -97,7 +97,8 @@ namespace ScriptCanvasEditor } AZ::Outcome openOutcome = AZ::Failure(AZStd::string()); - GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, SourceHandle( nullptr, assetInfo.m_assetId.m_guid, {} ), -1); + GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset + , SourceHandle( nullptr, assetInfo.m_assetId.m_guid, {} ), Tracker::ScriptCanvasFileState::UNMODIFIED, -1); return openOutcome.IsSuccess(); } diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/RequestBus.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/RequestBus.h index 90468f5d8c..15600c2b88 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/RequestBus.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Bus/RequestBus.h @@ -47,6 +47,18 @@ namespace ScriptCanvasEditor struct CategoryInformation; struct NodePaletteModelInformation; + namespace Tracker + { + enum class ScriptCanvasFileState : AZ::s32 + { + NEW, + MODIFIED, + UNMODIFIED, + // #sc_editor_asset restore this + SOURCE_REMOVED, + INVALID = -1 + }; + } namespace Widget { @@ -68,8 +80,8 @@ namespace ScriptCanvasEditor //! Opens an existing graph and returns the tab index in which it was open in. //! \param File AssetId //! \return index of open tab if the asset was able to be open successfully or error message of why the open failed - virtual AZ::Outcome OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, int tabIndex = -1) = 0; - virtual AZ::Outcome OpenScriptCanvasAssetId(const SourceHandle& scriptCanvasAsset) = 0; + virtual AZ::Outcome OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1) = 0; + virtual AZ::Outcome OpenScriptCanvasAssetId(const SourceHandle& scriptCanvasAsset, Tracker::ScriptCanvasFileState fileState) = 0; virtual int CloseScriptCanvasAsset(const SourceHandle&) = 0; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h index f9ea8b08e5..ddd83d06ba 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorScriptCanvasComponent.h @@ -85,12 +85,7 @@ namespace ScriptCanvasEditor AZ::Data::AssetId GetAssetId() const override; //===================================================================== - //===================================================================== - // AssetTrackerNotificationBus - void OnAssetReady(const ScriptCanvasMemoryAsset::pointer asset) ; - void OnAssetSaved(const ScriptCanvasMemoryAsset::pointer asset, bool isSuccessful) ; - void OnAssetReloaded(const ScriptCanvasMemoryAsset::pointer asset) ; - //===================================================================== + //===================================================================== @@ -119,7 +114,6 @@ namespace ScriptCanvasEditor // complete the id, load call OnScriptCanvasAssetChanged void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override; - // update the display icon for failure, save the values in the graph void SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override; void SourceFileFailed(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override; diff --git a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h index 7685133ca4..0d27d255af 100644 --- a/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h +++ b/Gems/ScriptCanvas/Code/Editor/Include/ScriptCanvas/Components/EditorUtils.h @@ -21,6 +21,9 @@ namespace GraphCanvas namespace ScriptCanvasEditor { + // If only the Path or the Id is valid, attempts to fill in the missing piece. + // If both Path and Id is valid, including after correction, returns the handle including source Data, + // otherwise, returns null AZStd::optional CompleteDescription(const SourceHandle& source); class Graph; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.cpp index cc43098ad4..2e0ace4768 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.cpp @@ -46,9 +46,9 @@ namespace ScriptCanvasEditor connect(this, &QTabBar::customContextMenuRequested, this, &GraphTabBar::OnContextMenu); } - void GraphTabBar::AddGraphTab(ScriptCanvasEditor::SourceHandle assetId) + void GraphTabBar::AddGraphTab(ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState) { - InsertGraphTab(count(), assetId); + InsertGraphTab(count(), assetId, fileState); } void GraphTabBar::ClearTabView(int tabIndex) @@ -143,7 +143,7 @@ namespace ScriptCanvasEditor } } - int GraphTabBar::InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId) + int GraphTabBar::InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState) { if (!SelectTab(assetId)) { @@ -159,9 +159,6 @@ namespace ScriptCanvasEditor AzFramework::StringFunc::Path::GetFileName(assetId.Path().c_str(), tabName); metaData.m_name = tabName.c_str(); - // #sc_editor_asset filestate - Tracker::ScriptCanvasFileState fileState = Tracker::ScriptCanvasFileState::INVALID; - // AssetTrackerRequestBus::BroadcastResult(fileState, &AssetTrackerRequests::GetFileState, fileAssetId); SetTabText(tabIndex, tabName.c_str(), fileState); setTabData(tabIndex, QVariant::fromValue(metaData)); return tabIndex; diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.h b/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.h index 48f327b244..9d86583f76 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/GraphTabBar.h @@ -18,6 +18,8 @@ #include #include +#include + #endif class QGraphicsView; @@ -54,11 +56,11 @@ namespace ScriptCanvasEditor void SetTabData(const GraphTabMetadata& data, int index); void SetTabData(const GraphTabMetadata& data, ScriptCanvasEditor::SourceHandle assetId); - void AddGraphTab(ScriptCanvasEditor::SourceHandle assetId); + void AddGraphTab(ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState); void CloseTab(int index); void CloseAllTabs(); - int InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId); + int InsertGraphTab(int tabIndex, ScriptCanvasEditor::SourceHandle assetId, Tracker::ScriptCanvasFileState fileState); bool SelectTab(ScriptCanvasEditor::SourceHandle assetId); // void ConfigureTab(int tabIndex, ScriptCanvasEditor::SourceHandle fileAssetId, const AZStd::string& tabName); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingWindowSession.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingWindowSession.cpp index 2e712cef08..963be52edc 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingWindowSession.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/LoggingPanel/LoggingWindowSession.cpp @@ -256,7 +256,8 @@ namespace ScriptCanvasEditor const AZ::Data::AssetId& assetId = executionItem->GetAssetId(); - GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, SourceHandle(nullptr, assetId.m_guid, {})); + GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId + , SourceHandle(nullptr, assetId.m_guid, {}), Tracker::ScriptCanvasFileState::UNMODIFIED); } } } @@ -272,10 +273,12 @@ namespace ScriptCanvasEditor bool isAssetOpen = false; GeneralRequestBus::BroadcastResult(isAssetOpen, &GeneralRequests::IsScriptCanvasAssetOpen, SourceHandle(nullptr, assetId.m_guid, {})); - GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId, SourceHandle(nullptr, assetId.m_guid, {})); + GeneralRequestBus::Broadcast(&GeneralRequests::OpenScriptCanvasAssetId + , SourceHandle(nullptr, assetId.m_guid, {}), Tracker::ScriptCanvasFileState::UNMODIFIED); AZ::EntityId graphCanvasGraphId; - GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId, SourceHandle(nullptr, assetId.m_guid, {})); + GeneralRequestBus::BroadcastResult(graphCanvasGraphId, &GeneralRequests::FindGraphCanvasGraphIdByAssetId + , SourceHandle(nullptr, assetId.m_guid, {})); if (isAssetOpen) { diff --git a/Gems/ScriptCanvas/Code/Editor/View/Widgets/UnitTestPanel/UnitTestDockWidget.cpp b/Gems/ScriptCanvas/Code/Editor/View/Widgets/UnitTestPanel/UnitTestDockWidget.cpp index a60c59ad7e..f319a166df 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Widgets/UnitTestPanel/UnitTestDockWidget.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Widgets/UnitTestPanel/UnitTestDockWidget.cpp @@ -433,7 +433,10 @@ namespace ScriptCanvasEditor AZ::Data::AssetId sourceAssetId(sourceUuid, 0); AZ::Outcome openOutcome = AZ::Failure(AZStd::string()); - GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAssetId, ScriptCanvasEditor::SourceHandle(nullptr, sourceUuid, {})); + GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAssetId + , ScriptCanvasEditor::SourceHandle(nullptr, sourceUuid, {}) + , Tracker::ScriptCanvasFileState::UNMODIFIED); + if (!openOutcome) { AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data()); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index d5182351fd..8da7ac1570 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -664,6 +664,7 @@ namespace ScriptCanvasEditor AzToolsFramework::ToolsApplicationNotificationBus::Handler::BusConnect(); AzToolsFramework::AssetSystemBus::Handler::BusConnect(); ScriptCanvas::ScriptCanvasSettingsRequestBus::Handler::BusConnect(); + AZ::SystemTickBus::Handler::BusConnect(); UINotificationBus::Broadcast(&UINotifications::MainWindowCreationEvent, this); @@ -1110,13 +1111,47 @@ namespace ScriptCanvasEditor RestartAutoTimerSave(forceTimer); } + void MainWindow::SourceFileChanged + ( [[maybe_unused]] AZStd::string relativePath + , AZStd::string scanFolder + , [[maybe_unused]] AZ::Uuid fileAssetId) + { + auto handle = CompleteDescription(SourceHandle(nullptr, fileAssetId, {})); + if (handle) + { + if (!IsRecentSave(*handle)) + { + UpdateFileState(*handle, Tracker::ScriptCanvasFileState::MODIFIED); + } + else + { + AZ_TracePrintf + ( "ScriptCanvas" + , "Ignoring source file modification notification (possibly external), as a it was recently saved by the editor: %s" + , relativePath.c_str()); + } + } + } + void MainWindow::SourceFileRemoved ( AZStd::string relativePath , [[maybe_unused]] AZStd::string scanFolder - , [[maybe_unused]] AZ::Uuid fileAssetId) + , AZ::Uuid fileAssetId) { - ScriptCanvasEditor::SourceHandle handle(nullptr, fileAssetId, relativePath); - UpdateFileState(handle, Tracker::ScriptCanvasFileState::SOURCE_REMOVED); + SourceHandle handle(nullptr, fileAssetId, relativePath); + { + if (!IsRecentSave(handle)) + { + UpdateFileState(handle, Tracker::ScriptCanvasFileState::SOURCE_REMOVED); + } + else + { + AZ_TracePrintf + ( "ScriptCanvas" + , "Ignoring source file removed notification (possibly external), as a it was recently saved by the editor: %s" + , relativePath.c_str()); + } + } } void MainWindow::SignalSceneDirty(ScriptCanvasEditor::SourceHandle assetId) @@ -1147,21 +1182,7 @@ namespace ScriptCanvasEditor m_tabBar->UpdateFileState(assetId, fileState); } - void MainWindow::RefreshScriptCanvasAsset(const AZ::Data::Asset& /*asset*/) - { - // #sc_editor_asset - /* - ScriptCanvasMemoryAsset::pointer memoryAsset; - AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, asset.GetId()); - - if (memoryAsset && asset.IsReady()) - { - - } - */ - } - - AZ::Outcome MainWindow::OpenScriptCanvasAssetId(const ScriptCanvasEditor::SourceHandle& fileAssetId) + AZ::Outcome MainWindow::OpenScriptCanvasAssetId(const ScriptCanvasEditor::SourceHandle& fileAssetId, Tracker::ScriptCanvasFileState fileState) { if (fileAssetId.Id().IsNull()) { @@ -1176,7 +1197,7 @@ namespace ScriptCanvasEditor return AZ::Success(outTabIndex); } - outTabIndex = CreateAssetTab(fileAssetId); + outTabIndex = CreateAssetTab(fileAssetId, fileState); if (!m_isRestoringWorkspace) { @@ -1186,7 +1207,7 @@ namespace ScriptCanvasEditor if (outTabIndex >= 0) { AddRecentFile(fileAssetId.Path().c_str()); - OpenScriptCanvasAssetImplementation(fileAssetId); + OpenScriptCanvasAssetImplementation(fileAssetId, fileState); return AZ::Success(outTabIndex); } else @@ -1195,7 +1216,7 @@ namespace ScriptCanvasEditor } } - AZ::Outcome MainWindow::OpenScriptCanvasAssetImplementation(const SourceHandle& scriptCanvasAsset, int tabIndex) + AZ::Outcome MainWindow::OpenScriptCanvasAssetImplementation(const SourceHandle& scriptCanvasAsset, Tracker::ScriptCanvasFileState fileState, int tabIndex) { const ScriptCanvasEditor::SourceHandle& fileAssetId = scriptCanvasAsset; if (!fileAssetId.IsValid()) @@ -1237,7 +1258,7 @@ namespace ScriptCanvasEditor return AZ::Success(outTabIndex); } - outTabIndex = CreateAssetTab(fileAssetId, tabIndex); + outTabIndex = CreateAssetTab(fileAssetId, fileState, tabIndex); if (outTabIndex == -1) { @@ -1257,21 +1278,21 @@ namespace ScriptCanvasEditor return AZ::Success(outTabIndex); } - AZ::Outcome MainWindow::OpenScriptCanvasAsset(ScriptCanvasEditor::SourceHandle scriptCanvasAssetId, int tabIndex) + AZ::Outcome MainWindow::OpenScriptCanvasAsset(ScriptCanvasEditor::SourceHandle scriptCanvasAssetId, Tracker::ScriptCanvasFileState fileState, int tabIndex) { if (scriptCanvasAssetId.IsValid()) { - return OpenScriptCanvasAssetImplementation(scriptCanvasAssetId, tabIndex); + return OpenScriptCanvasAssetImplementation(scriptCanvasAssetId, fileState, tabIndex); } else { - return OpenScriptCanvasAssetId(scriptCanvasAssetId); + return OpenScriptCanvasAssetId(scriptCanvasAssetId, fileState); } } - int MainWindow::CreateAssetTab(const ScriptCanvasEditor::SourceHandle& assetId, int tabIndex) + int MainWindow::CreateAssetTab(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState, int tabIndex) { - return m_tabBar->InsertGraphTab(tabIndex, assetId); + return m_tabBar->InsertGraphTab(tabIndex, assetId, fileState); } void MainWindow::RemoveScriptCanvasAsset(const ScriptCanvasEditor::SourceHandle& assetId) @@ -1314,7 +1335,7 @@ namespace ScriptCanvasEditor { if (createdAssetPair.second == requestingEntityId) { - return OpenScriptCanvasAssetId(createdAssetPair.first).IsSuccess(); + return OpenScriptCanvasAssetId(createdAssetPair.first, Tracker::ScriptCanvasFileState::NEW).IsSuccess(); } } @@ -1353,33 +1374,6 @@ namespace ScriptCanvasEditor return m_nodePaletteModel.FindNodePaletteInformation(nodeType); } - void MainWindow::GetSuggestedFullFilenameToSaveAs(const ScriptCanvasEditor::SourceHandle& /*assetId*/, AZStd::string& /*filePath*/, AZStd::string& /*fileFilter*/) - { - // #sc_editor_asset -// -// ScriptCanvasMemoryAsset::pointer memoryAsset; -// AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetId); -// -// AZStd::string assetPath; -// if (memoryAsset) -// { -// assetPath = memoryAsset->GetAbsolutePath(); -// fileFilter = ScriptCanvasAssetDescription().GetFileFilterImpl(); -// -// AZStd::string tabName; -// AssetTrackerRequestBus::BroadcastResult(tabName, &AssetTrackerRequests::GetTabName, assetId); -// -// assetPath = AZStd::string::format("%s/%s%s" -// , ScriptCanvasAssetDescription().GetSuggestedSavePathImpl() -// , tabName.c_str() -// , ScriptCanvasAssetDescription().GetExtensionImpl()); -// } -// -// AZStd::array resolvedPath; -// AZ::IO::FileIOBase::GetInstance()->ResolvePath(assetPath.data(), resolvedPath.data(), resolvedPath.size()); -// filePath = resolvedPath.data(); - } - void MainWindow::OpenFile(const char* fullPath) { auto tabIndex = m_tabBar->FindTabByPath(fullPath); @@ -1416,7 +1410,7 @@ namespace ScriptCanvasEditor m_errorFilePath.clear(); auto activeGraph = ScriptCanvasEditor::SourceHandle(outcome.TakeValue(), assetInfo.m_assetId.m_guid, fullPath); - auto openOutcome = OpenScriptCanvasAsset(activeGraph); + auto openOutcome = OpenScriptCanvasAsset(activeGraph, Tracker::ScriptCanvasFileState::UNMODIFIED); if (openOutcome) { RunGraphValidation(false); @@ -1427,66 +1421,10 @@ namespace ScriptCanvasEditor { AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data()); } - -#if defined(EDITOR_ASSET_SUPPORT_ENABLED) - /* - m_errorFilePath = fullPath; - - // Let's find the source file on disk - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, fullPath, assetInfo, watchFolder); - - if (sourceInfoFound) - { - const Tracker::ScriptCanvasFileState& fileState = GetAssetFileState(assetInfo.m_assetId); - if (fileState != Tracker::ScriptCanvasFileState::NEW && fileState != Tracker::ScriptCanvasFileState::INVALID) - { - ScriptCanvasMemoryAsset::pointer memoryAsset; - AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetInfo.m_assetId); - - if (m_tabBar->FindTab(assetInfo.m_assetId) < 0) - { - CreateAssetTab(assetInfo.m_assetId); - } - - SetActiveAsset(memoryAsset->GetFileAssetId()); - OpenNextFile(); - return; - } - - Callbacks::OnAssetReadyCallback onAssetReady = [this, assetInfo](ScriptCanvasMemoryAsset&) - { - ScriptCanvasMemoryAsset::pointer memoryAsset; - AssetTrackerRequestBus::BroadcastResult(memoryAsset, &AssetTrackerRequests::GetAsset, assetInfo.m_assetId); - - auto openOutcome = OpenScriptCanvasAsset(*memoryAsset); - if (openOutcome) - { - RunGraphValidation(false); - SetRecentAssetId(assetInfo.m_assetId); - } - else - { - AZ_Warning("Script Canvas", openOutcome, "%s", openOutcome.GetError().data()); - } - - OpenNextFile(); - }; - - // TODO-LS the assetInfo.m_assetType is always null for some reason, I know in this case we want default assets so it's ok to hardcode it - AssetTrackerRequestBus::Broadcast(&AssetTrackerRequests::Load, assetInfo.m_assetId, assetInfo.m_assetType, azrtti_typeid(), onAssetReady); - } - else - { - QMessageBox::warning(this, "Invalid Source Asset", QString("'%1' is not a valid asset path.").arg(fullPath), QMessageBox::Ok); - } - */ -#endif } - GraphCanvas::Endpoint MainWindow::HandleProposedConnection(const GraphCanvas::GraphId&, const GraphCanvas::ConnectionId&, const GraphCanvas::Endpoint& endpoint, const GraphCanvas::NodeId& nodeId, const QPoint& screenPoint) + GraphCanvas::Endpoint MainWindow::HandleProposedConnection(const GraphCanvas::GraphId&, const GraphCanvas::ConnectionId& + , const GraphCanvas::Endpoint& endpoint, const GraphCanvas::NodeId& nodeId, const QPoint& screenPoint) { GraphCanvas::Endpoint retVal; @@ -1631,7 +1569,7 @@ namespace ScriptCanvasEditor // Insert tab block AZStd::string tabName; AzFramework::StringFunc::Path::GetFileName(assetPath.data(), tabName); - m_tabBar->InsertGraphTab(tabIndex, assetId); + m_tabBar->InsertGraphTab(tabIndex, assetId, Tracker::ScriptCanvasFileState::NEW); if (!IsTabOpen(assetId, outTabIndex)) { @@ -1664,17 +1602,13 @@ namespace ScriptCanvasEditor ScriptCanvasEditor::SourceHandle handle = ScriptCanvasEditor::SourceHandle(graph, assetId, assetPath); outTabIndex = InsertTabForAsset(assetPath, handle, tabIndex); - m_tabBar->UpdateFileState(handle, Tracker::ScriptCanvasFileState::NEW); - + if (outTabIndex == -1) { return AZ::Failure(AZStd::string::format("Script Canvas Asset %.*s is not open in a tab", assetPath.data())); } SetActiveAsset(handle); - - // #sc_editor_asset delete candidate - PushPreventUndoStateUpdate(); AZ::EntityId scriptCanvasEntityId = graph->GetGraph()->GetScriptCanvasId(); @@ -1788,7 +1722,6 @@ namespace ScriptCanvasEditor } else { - // replaces GetSuggestedFullFilenameToSaveAs suggestedFileFilter = ScriptCanvasAssetDescription().GetExtensionImpl(); if (inMemoryAssetId.Path().empty()) @@ -1878,7 +1811,8 @@ namespace ScriptCanvasEditor void MainWindow::OnSaveCallBack(const VersionExplorer::FileSaveResult& result) { const bool saveSuccess = result.fileSaveError.empty(); - auto memoryAsset = m_fileSaver->GetSource(); + auto completeDescription = CompleteDescription(m_fileSaver->GetSource()); + auto memoryAsset = completeDescription ? *completeDescription : m_fileSaver->GetSource(); int saveTabIndex = m_tabBar->FindTab(memoryAsset); AZStd::string tabName = saveTabIndex >= 0 ? m_tabBar->tabText(saveTabIndex).toUtf8().data() : ""; @@ -2000,18 +1934,11 @@ namespace ScriptCanvasEditor const bool displayAsNotification = true; RunGraphValidation(displayAsNotification); - // This is called during saving, so the is saving flag is always true Need to update the state after this callback is complete. So schedule for next system tick. - AddSystemTickAction(SystemTickActionFlag::UpdateSaveMenuState); - - if (saveSuccess && m_closeCurrentGraphAfterSave) - { - AddSystemTickAction(SystemTickActionFlag::CloseCurrentGraph); - } - m_closeCurrentGraphAfterSave = false; EnableAssetView(memoryAsset); + UpdateSaveState(true); UnblockCloseRequests(); m_fileSaver.reset(); } @@ -2025,15 +1952,15 @@ namespace ScriptCanvasEditor void MainWindow::SaveAs(AZStd::string_view path, ScriptCanvasEditor::SourceHandle inMemoryAssetId) { DisableAssetView(inMemoryAssetId); - + UpdateSaveState(false); m_fileSaver = AZStd::make_unique ( nullptr , [this](const VersionExplorer::FileSaveResult& fileSaveResult) { OnSaveCallBack(fileSaveResult); }); - ScriptCanvasEditor::SourceHandle newLocation(inMemoryAssetId, {}, path); + ScriptCanvasEditor::SourceHandle newLocation(inMemoryAssetId, AZ::Uuid::CreateNull(), path); + MarkRecentSave(newLocation); m_fileSaver->Save(newLocation); - UpdateSaveState(); BlockCloseRequests(); } @@ -2825,7 +2752,6 @@ namespace ScriptCanvasEditor void MainWindow::OnActiveFileStateChanged() { - UpdateSaveState(); UpdateAssignToSelectionState(); } @@ -3455,7 +3381,6 @@ namespace ScriptCanvasEditor UpdateAssignToSelectionState(); UpdateUndoRedoState(); - UpdateSaveState(); } void MainWindow::OnWorkspaceRestoreStart() @@ -3533,25 +3458,10 @@ namespace ScriptCanvasEditor ui->action_Redo->setEnabled(isEnabled); } - void MainWindow::UpdateSaveState() + void MainWindow::UpdateSaveState(bool enabled) { - // #sc_editor_asset todo, consider making blocking -// bool enabled = m_activeGraph.IsValid(); -// bool isSaving = false; -// bool hasModifications = false; -// -// if (enabled) -// { -// Tracker::ScriptCanvasFileState fileState = GetAssetFileState(m_activeGraph); -// hasModifications = ( fileState == Tracker::ScriptCanvasFileState::MODIFIED -// || fileState == Tracker::ScriptCanvasFileState::NEW -// || fileState == Tracker::ScriptCanvasFileState::SOURCE_REMOVED); -// -// AssetTrackerRequestBus::BroadcastResult(isSaving, &AssetTrackerRequests::IsSaving, m_activeGraph); -// } -// -// ui->action_Save->setEnabled(enabled && !isSaving && hasModifications); -// ui->action_Save_As->setEnabled(enabled && !isSaving); + ui->action_Save->setEnabled(enabled); + ui->action_Save_As->setEnabled(enabled); } void MainWindow::CreateFunctionInput() @@ -4141,12 +4051,6 @@ namespace ScriptCanvasEditor qobject_cast(parent())->close(); } - if (HasSystemTickAction(SystemTickActionFlag::UpdateSaveMenuState)) - { - RemoveSystemTickAction(SystemTickActionFlag::UpdateSaveMenuState); - UpdateSaveState(); - } - if (HasSystemTickAction(SystemTickActionFlag::CloseCurrentGraph)) { RemoveSystemTickAction(SystemTickActionFlag::CloseCurrentGraph); @@ -4163,10 +4067,7 @@ namespace ScriptCanvasEditor CloseNextTab(); } - if (m_systemTickActions == 0) - { - AZ::SystemTickBus::Handler::BusDisconnect(); - } + ClearStaleSaves(); } void MainWindow::OnCommandStarted(AZ::Crc32) @@ -4393,11 +4294,6 @@ namespace ScriptCanvasEditor void MainWindow::AddSystemTickAction(SystemTickActionFlag action) { - if (!AZ::SystemTickBus::Handler::BusIsConnected()) - { - AZ::SystemTickBus::Handler::BusConnect(); - } - m_systemTickActions |= action; } @@ -4747,5 +4643,34 @@ namespace ScriptCanvasEditor UpdateUndoRedoState(); } + + void MainWindow::ClearStaleSaves() + { + AZStd::lock_guard lock(m_mutex); + auto timeNow = AZStd::chrono::system_clock::now(); + AZStd::erase_if(m_saves, [&timeNow](const auto& item) + { + AZStd::sys_time_t delta = AZStd::chrono::seconds(timeNow - item.second).count(); + return delta > 2.0f; + }); + } + + bool MainWindow::IsRecentSave(const SourceHandle& handle) const + { + AZStd::lock_guard lock(const_cast(this)->m_mutex); + AZStd::string key = handle.Path().Native(); + AZStd::to_lower(key.begin(), key.end()); + auto iter = m_saves.find(key); + return iter != m_saves.end(); + } + + void MainWindow::MarkRecentSave(const SourceHandle& handle) + { + AZStd::lock_guard lock(m_mutex); + AZStd::string key = handle.Path().Native(); + AZStd::to_lower(key.begin(), key.end()); + m_saves[key] = AZStd::chrono::system_clock::now(); + } + #include } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h index dfe5d9fa13..68488238ec 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h @@ -425,9 +425,9 @@ namespace ScriptCanvasEditor QVariant GetTabData(const SourceHandle& assetId); //! GeneralRequestBus - AZ::Outcome OpenScriptCanvasAssetId(const SourceHandle& assetId) override; - AZ::Outcome OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, int tabIndex = -1) override; - AZ::Outcome OpenScriptCanvasAssetImplementation(const SourceHandle& sourceHandle, int tabIndex = -1); + AZ::Outcome OpenScriptCanvasAssetId(const SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState) override; + AZ::Outcome OpenScriptCanvasAsset(SourceHandle scriptCanvasAssetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1) override; + AZ::Outcome OpenScriptCanvasAssetImplementation(const SourceHandle& sourceHandle, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1); int CloseScriptCanvasAsset(const SourceHandle& assetId) override; bool CreateScriptCanvasAssetFor(const TypeDefs::EntityComponentId& requestingEntityId) override; @@ -438,8 +438,7 @@ namespace ScriptCanvasEditor //// AZ::Outcome CreateScriptCanvasAsset(AZStd::string_view assetPath, int tabIndex = -1); - void RefreshScriptCanvasAsset(const AZ::Data::Asset& scriptCanvasAsset); - + //! Removes the assetId -> ScriptCanvasAsset mapping and disconnects from the asset tracker void RemoveScriptCanvasAsset(const ScriptCanvasEditor::SourceHandle& assetId); void OnChangeActiveGraphTab(ScriptCanvasEditor::SourceHandle) override; @@ -525,8 +524,9 @@ namespace ScriptCanvasEditor AZ::EntityId FindAssetNodeIdByEditorNodeId(const ScriptCanvasEditor::SourceHandle& assetId, AZ::EntityId editorNodeId) const override; private: + void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override; void SourceFileRemoved(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override; - + void DeleteNodes(const AZ::EntityId& sceneId, const AZStd::vector& nodes) override; void DeleteConnections(const AZ::EntityId& sceneId, const AZStd::vector& connections) override; void DisconnectEndpoints(const AZ::EntityId& sceneId, const AZStd::vector& endpoints) override; @@ -549,11 +549,6 @@ namespace ScriptCanvasEditor void OnAutoSave(); - //! Helper function which serializes a file to disk - //! \param filename name of file to serialize the Entity - //! \param asset asset to save - void GetSuggestedFullFilenameToSaveAs(const ScriptCanvasEditor::SourceHandle& assetId, AZStd::string& filePath, AZStd::string& fileFilter); - void UpdateFileState(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState); // QMainWindow @@ -599,14 +594,14 @@ namespace ScriptCanvasEditor void UpdateAssignToSelectionState(); void UpdateUndoRedoState(); - void UpdateSaveState(); + void UpdateSaveState(bool enabled); void CreateFunctionInput(); void CreateFunctionOutput(); void CreateFunctionDefinitionNode(int positionOffset); - int CreateAssetTab(const ScriptCanvasEditor::SourceHandle& assetId, int tabIndex = -1); + int CreateAssetTab(const ScriptCanvasEditor::SourceHandle& assetId, Tracker::ScriptCanvasFileState fileState, int tabIndex = -1); //! \param asset The AssetId of the ScriptCanvas Asset. void SetActiveAsset(const ScriptCanvasEditor::SourceHandle& assetId); @@ -767,5 +762,11 @@ namespace ScriptCanvasEditor AZStd::unique_ptr m_fileSaver; VersionExplorer::FileSaveResult m_fileSaveResult; void OnSaveCallBack(const VersionExplorer::FileSaveResult& result); + + void ClearStaleSaves(); + bool IsRecentSave(const SourceHandle& handle) const; + void MarkRecentSave(const SourceHandle& handle); + AZStd::recursive_mutex m_mutex; + AZStd::unordered_map m_saves; }; } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.cpp index 3522f3cfa2..c557a83f0c 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.cpp @@ -98,7 +98,7 @@ namespace ScriptCanvasEditor if (!asset.Path().empty()) { - GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, asset, -1); + GeneralRequestBus::BroadcastResult(openOutcome, &GeneralRequests::OpenScriptCanvasAsset, asset, Tracker::ScriptCanvasFileState::UNMODIFIED, -1); } if (!openOutcome) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp index ae85dbc6a9..1b24d2d12a 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.cpp @@ -194,14 +194,18 @@ namespace ScriptCanvasEditor , m_id(id) , m_path(path) { - + m_path.MakePreferred(); + m_id = id; } SourceHandle::SourceHandle(ScriptCanvas::DataPtr graph, const AZ::Uuid& id, const AZ::IO::Path& path) : m_data(graph) , m_id(id) , m_path(path) - {} + { + m_path.MakePreferred(); + m_id = id; + } bool SourceHandle::AnyEquals(const SourceHandle& other) const { diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h index d514683b55..8671197f7b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/Core.h @@ -27,8 +27,6 @@ #define OBJECT_STREAM_EDITOR_ASSET_LOADING_SUPPORT_ENABLED -// #define EDITOR_ASSET_SUPPORT_ENABLED - namespace AZ { class Entity;