From 0e2f75492c4ac67fdd475c62729912fb5365d50e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 14 Sep 2021 14:05:15 -0700 Subject: [PATCH] dependency sort finished, but not tested Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Windows/Tools/UpgradeTool/Controller.cpp | 4 +- .../Windows/Tools/UpgradeTool/Controller.h | 4 +- .../Windows/Tools/UpgradeTool/LogTraits.h | 1 + .../Windows/Tools/UpgradeTool/ModelTraits.h | 4 +- .../Windows/Tools/UpgradeTool/Modifier.cpp | 159 ++++++++++++++++-- .../View/Windows/Tools/UpgradeTool/Modifier.h | 21 ++- 6 files changed, 174 insertions(+), 19 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp index 09f0428901..8eae0e1bd0 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp @@ -342,7 +342,9 @@ namespace ScriptCanvasEditor } - void Controller::OnUpgradeAllDependencySortEnd(const AZStd::vector& sortedAssets) + void Controller::OnUpgradeAllDependencySortEnd + ( const AZStd::vector& sortedAssets + , [[maybe_unused]] const AZStd::vector& sortedOrder) { m_view->progressBar->setRange(0, aznumeric_cast(sortedAssets.size())); } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h index f7a0315730..e2f00fe6f3 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h @@ -78,7 +78,9 @@ namespace ScriptCanvasEditor void OnUpgradeAllBegin() override; void OnUpgradeAllComplete() override; void OnUpgradeAllDependencySortBegin() override; - void OnUpgradeAllDependencySortEnd(const AZStd::vector& sortedAssets) override; + void OnUpgradeAllDependencySortEnd + ( const AZStd::vector& sortedAssets + , const AZStd::vector& sortedOrder) override; }; } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/LogTraits.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/LogTraits.h index c75133f09e..47cebe7324 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/LogTraits.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/LogTraits.h @@ -8,6 +8,7 @@ #pragma once #include +#include #define VE_LOG(...) LogBus::Broadcast(&LogTraits::Entry, __VA_ARGS__); diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h index d01d311ebc..09ad2b01c1 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h @@ -63,7 +63,9 @@ namespace ScriptCanvasEditor virtual void OnUpgradeAllBegin() = 0; virtual void OnUpgradeAllComplete() = 0; virtual void OnUpgradeAllDependencySortBegin() = 0; - virtual void OnUpgradeAllDependencySortEnd(const AZStd::vector& sortedAssets) = 0; + virtual void OnUpgradeAllDependencySortEnd + ( const AZStd::vector& assets + , const AZStd::vector& sortedOrder) = 0; }; using ModelNotificationsBus = AZ::EBus; } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp index 9841a9f60e..1723b0f8ff 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp @@ -6,9 +6,11 @@ * */ +#include #include #include #include +#include namespace ModifierCpp { @@ -23,7 +25,8 @@ namespace ScriptCanvasEditor ( const ModifyConfiguration& modification , AZStd::vector&& assets , AZStd::function onComplete) - : m_config(modification) + : m_state(State::GatheringDependencies) + , m_config(modification) , m_assets(assets) , m_onComplete(onComplete) { @@ -31,12 +34,22 @@ namespace ScriptCanvasEditor AZ::SystemTickBus::Handler::BusConnect(); } - const AZ::Data::AssetInfo& Modifier::GetCurrentAsset() const { return m_state == State::GatheringDependencies ? m_assets[m_assetIndex] - : m_assets[m_dependencyOrderedIndicies[m_assetIndex]]; + : m_assets[m_dependencyOrderedAssetIndicies[m_assetIndex]]; + } + + AZStd::unordered_set& Modifier::GetOrCreateDependencyIndexSet() + { + auto iter = m_dependencies.find(m_assetIndex); + if (iter == m_dependencies.end()) + { + iter = m_dependencies.insert_or_assign(m_assetIndex, AZStd::unordered_set()).first; + } + + return iter->second; } void Modifier::GatherDependencies() @@ -45,10 +58,19 @@ namespace ScriptCanvasEditor AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); AZ_Assert(serializeContext, "SerializeContext is required to enumerate dependent assets in the ScriptCanvas file"); - /* + auto asset = LoadAsset(); + if (!asset + || !asset.GetAs() + || !asset.GetAs()->GetScriptCanvasGraph() + || !asset.GetAs()->GetScriptCanvasGraph()->GetGraphData()) + { + VE_LOG("Modifier: Failed to load asset %s for modification, even though it scanned properly"); + return; + } - // AZStd::unordered_multimap jobDependenciesByKey; - auto assetFilter = [this, &jobDependenciesByKey] + auto graphData = asset.GetAs()->GetScriptCanvasGraph()->GetGraphData(); + + auto dependencyGrabber = [this] ( void* instancePointer , const AZ::SerializeContext::ClassData* classData , [[maybe_unused]] const AZ::SerializeContext::ClassElement* classElement) @@ -59,11 +81,15 @@ namespace ScriptCanvasEditor 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 }); + if (auto iter = m_assetInfoIndexById.find(subgraphAsset->GetId().m_guid); iter != m_assetInfoIndexById.end()) + { + GetOrCreateDependencyIndexSet().insert(iter->second); + } + else + { + VE_LOG("Modifier: Dependency found that was not picked up by the scanner: %s" + , subgraphAsset->GetId().ToString().c_str()); + } } } // always continue, make note of the script canvas dependencies @@ -71,9 +97,9 @@ namespace ScriptCanvasEditor }; AZ_Verify(serializeContext->EnumerateInstanceConst - ( sourceGraph->GetGraphData() + ( graphData , azrtti_typeid() - , assetFilter + , dependencyGrabber , {} , AZ::SerializeContext::ENUM_ACCESS_FOR_READ , nullptr @@ -81,13 +107,12 @@ namespace ScriptCanvasEditor // Flush asset database events to ensure no asset references are held by closures queued on Ebuses. AZ::Data::AssetManager::Instance().DispatchEvents(); - */ } AZ::Data::Asset Modifier::LoadAsset() { AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - (GetCurrentAsset().m_assetId + ( GetCurrentAsset().m_assetId , azrtti_typeid() , AZ::Data::AssetLoadBehavior::PreLoad); @@ -116,5 +141,109 @@ namespace ScriptCanvasEditor break; } } + + const AZStd::unordered_set* Modifier::Sorter::GetDependencies(size_t index) const + { + auto iter = modifier->m_dependencies.find(index); + return iter != modifier->m_dependencies.end() ? &iter->second : nullptr; + } + + void Modifier::Sorter::Sort() + { + for (size_t index = 0; index != modifier->m_assets.size(); ++index) + { + Visit(index); + } + /* + L ← Empty list that will contain the sorted nodes + (m_dependencyOrderedAssetIndicies) + + while exists nodes without a permanent mark do + select an unmarked node n + visit(n) + */ + } + + void Modifier::Sorter::Visit(size_t index) + { + if (markedPermanent.contains(index)) + { + return; + } + + if (markedTemporary.contains(index)) + { + AZ_Error + ( ScriptCanvas::k_VersionExplorerWindow.data() + , false + , "Modifier: Dependency sort has failed during, circular dependency detected for Asset: %s" + , modifier->GetCurrentAsset().m_relativePath.c_str()); + return; + } + + markedTemporary.insert(index); + + if (auto dependencies = GetDependencies(index)) + { + for (auto& dependency : *dependencies) + { + Visit(dependency); + } + } + + markedTemporary.erase(index); + markedPermanent.insert(index); + modifier->m_dependencyOrderedAssetIndicies.push_back(index); + } + + void Modifier::SortGraphsByDependencies() + { + m_dependencyOrderedAssetIndicies.reserve(m_assets.size()); + Sorter sorter; + sorter.modifier = this; + sorter.Sort(); + } + + void Modifier::TickGatherDependencies() + { + if (m_assetIndex == 0) + { + if (m_config.successfulDependencyUpgradeRequired) + { + ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeAllDependencySortBegin); + m_assetInfoIndexById.reserve(m_assets.size()); + + for (size_t index = 0; index != m_assets.size(); ++index) + { + m_assetInfoIndexById.insert({ m_assets[index].m_assetId.m_guid, index }); + } + } + else + { + m_dependencyOrderedAssetIndicies.reserve(m_assets.size()); + + for (size_t index = 0; index != m_assets.size(); ++index) + { + m_dependencyOrderedAssetIndicies.push_back(index); + } + } + } + + if (m_assetIndex == m_assets.size()) + { + SortGraphsByDependencies(); + ModelNotificationsBus::Broadcast + ( &ModelNotificationsTraits::OnUpgradeAllDependencySortEnd + , m_assets + , m_dependencyOrderedAssetIndicies); + m_assetIndex = 0; + m_state = State::ModifyingGraphs; + } + else + { + GatherDependencies(); + ++m_assetIndex; + } + } } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h index b862de82f0..e0b1f1a289 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h @@ -28,6 +28,20 @@ namespace ScriptCanvasEditor , AZStd::function onComplete); private: + friend class Sorter; + + struct Sorter + { + Modifier* modifier; + AZStd::unordered_set markedPermanent; + AZStd::unordered_set markedTemporary; + void Sort(); + + private: + void Visit(size_t index); + const AZStd::unordered_set* GetDependencies(size_t index) const; + }; + enum class State { GatheringDependencies, @@ -37,15 +51,20 @@ namespace ScriptCanvasEditor State m_state = State::GatheringDependencies; size_t m_assetIndex = 0; AZStd::function m_onComplete; + // asset infos in scanned order AZStd::vector m_assets; - AZStd::vector m_dependencyOrderedIndicies; + // dependency sorted order indices into the asset vector + AZStd::vector m_dependencyOrderedAssetIndicies; + // dependency indices by asset info index (only exist if graphs have them) AZStd::unordered_map> m_dependencies; + AZStd::unordered_map m_assetInfoIndexById; AZStd::vector m_failures; ModifyConfiguration m_config; ModificationResult m_result; void GatherDependencies(); const AZ::Data::AssetInfo& GetCurrentAsset() const; + AZStd::unordered_set& GetOrCreateDependencyIndexSet(); AZ::Data::Asset LoadAsset(); void SortGraphsByDependencies(); void OnSystemTick() override;