浏览代码

Make version explorer wait on AP for dependent assets

Signed-off-by: carlitosan <[email protected]>
carlitosan 3 年之前
父节点
当前提交
d284d908b9

+ 2 - 1
Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp

@@ -281,7 +281,8 @@ namespace ScriptCanvasBuilder
                 }
                 else
                 {
-                    if (AzFramework::StringFunc::Find(fileNameOnly, s_unitTestParseErrorPrefix) != AZStd::string::npos)
+                    if (!ScriptCanvas::Grammar::g_processingErrorsForUnitTestsEnabled
+                        && AzFramework::StringFunc::Find(fileNameOnly, s_unitTestParseErrorPrefix) != AZStd::string::npos)
                     {
                         response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
                     }

+ 1 - 1
Gems/ScriptCanvas/Code/Editor/GraphCanvas/Components/NodeDescriptors/ScriptEventReceiverEventNodeDescriptorComponent.cpp

@@ -190,7 +190,7 @@ namespace ScriptCanvasEditor
                     {
                         scriptCanvasSlot = eventHandler->GetSlot(slotId);
 
-                        int& index = (scriptCanvasSlot->IsData() && scriptCanvasSlot->IsInput()) ? paramIndex : outputIndex;
+                        int& index = (scriptCanvasSlot && scriptCanvasSlot->IsData() && scriptCanvasSlot->IsInput()) ? paramIndex : outputIndex;
 
                         if (scriptCanvasSlot && scriptCanvasSlot->IsVisible())
                         {

+ 1 - 17
Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp

@@ -1880,10 +1880,6 @@ namespace ScriptCanvasEditor
 
     void MainWindow::OnFileOpen()
     {
-        AZ::SerializeContext* serializeContext = nullptr;
-        EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext);
-        AZ_Assert(serializeContext, "Failed to acquire application serialize context.");
-
         AZStd::string assetRoot;
         {
             AZStd::array<char, AZ::IO::MaxPathLength> assetRootChar;
@@ -1892,21 +1888,9 @@ namespace ScriptCanvasEditor
         }
 
         AZStd::string assetPath = AZStd::string::format("%s/scriptcanvas", assetRoot.c_str());
-
-        AZ::EBusAggregateResults<AZStd::vector<AZStd::string>> fileFilters;
-        AssetRegistryRequestBus::BroadcastResult(fileFilters, &AssetRegistryRequests::GetAssetHandlerFileFilters);
-
         QString filter;
 
-        AZStd::set<AZStd::string> filterSet;
-        auto aggregateFilters = fileFilters.values;
-        for (auto aggregateFilters2 : fileFilters.values)
-        {
-            for (const AZStd::string& fileFilter : aggregateFilters2)
-            {
-                filterSet.insert(fileFilter);
-            }
-        }
+        AZStd::set<AZStd::string> filterSet { ".scriptcanvas" };
 
         QStringList nameFilters;
 

+ 5 - 0
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp

@@ -189,6 +189,11 @@ namespace ScriptCanvasEditor
             OnButtonPressUpgradeImplementation(info);
         }
 
+        void Controller::OnUpgradeDependencyWaitInterval([[maybe_unused]] const SourceHandle& info)
+        {
+            AddLogEntries();
+        }
+
         void Controller::OnUpgradeModificationBegin([[maybe_unused]] const ModifyConfiguration& config, const SourceHandle& info)
         {
             for (auto* item : FindTableItems(info))

+ 2 - 1
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h

@@ -93,9 +93,10 @@ namespace ScriptCanvasEditor
                 ( const ModifyConfiguration& config
                 , const AZStd::vector<SourceHandle>& assets
                 , const AZStd::vector<size_t>& sortedOrder) override;
+            void OnUpgradeDependencyWaitInterval(const SourceHandle& info) override;
             void OnUpgradeModificationBegin(const ModifyConfiguration& config, const SourceHandle& info) override;
             void OnUpgradeModificationEnd(const ModifyConfiguration& config, const SourceHandle& info, ModificationResult result) override;
-
+            
             void SetLoggingPreferences();
             void SetSpinnerIsBusy(bool isBusy);
             void SetRowBusy(int index);

+ 2 - 0
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h

@@ -22,6 +22,7 @@ namespace ScriptCanvasEditor
             SourceHandle modifySingleAsset;
             bool backupGraphBeforeModification = false;
             bool successfulDependencyUpgradeRequired = true;
+            AZ::s32 perDependencyWaitSecondsMax = 20;
         };
 
         struct ModificationResult
@@ -98,6 +99,7 @@ namespace ScriptCanvasEditor
                 ( const ModifyConfiguration& config
                 , const AZStd::vector<SourceHandle>& assets
                 , const AZStd::vector<size_t>& sortedOrder) = 0;
+            virtual void OnUpgradeDependencyWaitInterval(const SourceHandle& info) = 0;
             virtual void OnUpgradeModificationBegin(const ModifyConfiguration& config, const SourceHandle& info) = 0;
             virtual void OnUpgradeModificationEnd(const ModifyConfiguration& config, const SourceHandle& info, ModificationResult result) = 0;
         };

+ 236 - 56
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp

@@ -30,38 +30,141 @@ namespace ScriptCanvasEditor
             AZ_Assert(m_config.modification, "No modification function provided");
             ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeBegin, modification, m_assets);
             AZ::SystemTickBus::Handler::BusConnect();
+            AzFramework::AssetSystemInfoBus::Handler::BusConnect();
+            AzFramework::AssetSystemInfoBus::Handler::BusConnect();
+            m_result.asset = m_assets[GetCurrentIndex()];
         }
 
-        size_t Modifier::GetCurrentIndex() const
+        Modifier::~Modifier()
         {
-            return m_state == State::GatheringDependencies
-                ? m_assetIndex
-                : m_dependencyOrderedAssetIndicies[m_assetIndex];
+            AzFramework::AssetSystemInfoBus::Handler::BusDisconnect();
+            AzFramework::AssetSystemInfoBus::Handler::BusDisconnect();
+        }
 
+        bool Modifier::AllDependenciesCleared(const AZStd::unordered_set<size_t>& dependencies) const
+        {
+            for (auto index : dependencies)
+            {
+                SourceHandle dependency = m_assets[index];
+                CompleteDescriptionInPlace(dependency);
+
+                if (dependency.Id().IsNull() || !m_assetsCompletedByAP.contains(dependency.Id()))
+                {
+                    return false;
+                }
+            }
+
+            return true;
         }
 
-        AZStd::unordered_set<size_t>& Modifier::GetOrCreateDependencyIndexSet()
+        bool Modifier::AnyDependenciesFailed(const AZStd::unordered_set<size_t>& dependencies) const
         {
-            auto iter = m_dependencies.find(m_assetIndex);
-            if (iter == m_dependencies.end())
+            for (auto index : dependencies)
             {
-                iter = m_dependencies.insert_or_assign(m_assetIndex, AZStd::unordered_set<size_t>()).first;
+                SourceHandle dependency = m_assets[index];
+                CompleteDescriptionInPlace(dependency);
+
+                if (dependency.Id().IsNull() || m_assetsFailedByAP.contains(dependency.Id()))
+                {
+                    return true;
+                }
             }
 
-            return iter->second;
+            return false;
         }
 
-        const ModificationResults& Modifier::GetResult() const
+        AZStd::sys_time_t Modifier::CalculateRemainingWaitTime(const AZStd::unordered_set<size_t>& dependencies) const
         {
-            return m_results;
+            auto maxSeconds = AZStd::chrono::seconds(dependencies.size() * m_config.perDependencyWaitSecondsMax);
+            auto waitedSeconds = AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_waitTimeStamp);
+            return (maxSeconds - waitedSeconds).count();
+        }
+
+        void Modifier::SourceFileChanged(AZStd::string relativePath, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
+        {
+            AZ_TracePrintf("SC", "received SourceFileChanged: %s", relativePath.c_str());
+            VE_LOG("received SourceFileChanged: %s", relativePath.c_str());
+        }
+
+        void Modifier::SourceFileFailed(AZStd::string relativePath, [[maybe_unused]] AZStd::string scanFolder, [[maybe_unused]] AZ::Uuid fileAssetId)
+        {
+            AZ_TracePrintf("SC", "received SourceFileFailed: %s", relativePath.c_str());
+            VE_LOG("received SourceFileFailed: %s", relativePath.c_str());
+        }
+
+        void Modifier::ProcessNotifications()
+        {
+            AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
+
+            for (const auto& assetPath : m_successNotifications)
+            {
+                VE_LOG("received AssetCompilationSuccess: %s", assetPath.c_str());
+                SourceHandle sourceHandle(nullptr, {}, assetPath.c_str());
+                CompleteDescriptionInPlace(sourceHandle);
+
+                if (m_attemptedAssets.contains(sourceHandle.Id()))
+                {
+                    m_assetsCompletedByAP.insert(sourceHandle.Id());
+                }
+            }
+
+            m_successNotifications.clear();
+
+            for (const auto& assetPath : m_failureNotifications)
+            {
+                VE_LOG("received AssetCompilationFailed: %s", assetPath.c_str());
+                SourceHandle sourceHandle(nullptr, {}, assetPath.c_str());
+                CompleteDescriptionInPlace(sourceHandle);
+
+                if (m_attemptedAssets.contains(sourceHandle.Id()))
+                {
+                    m_assetsFailedByAP.insert(sourceHandle.Id());
+                }
+            }
+
+            m_failureNotifications.clear();
+        }
+
+        void Modifier::AssetCompilationSuccess([[maybe_unused]] const AZStd::string& assetPath)
+        {
+            AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
+            // test failure path m_successNotifications.insert(assetPath);
+            m_failureNotifications.insert(assetPath);
+        }
+
+        void Modifier::AssetCompilationFailed(const AZStd::string& assetPath)
+        {
+            AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
+            m_failureNotifications.insert(assetPath);
+        }
+
+        void Modifier::CheckDependencies()
+        {
+            ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, m_result.asset);
+
+            if (auto dependencies = GetDependencies(GetCurrentIndex()); dependencies != nullptr && !dependencies->empty())
+            {
+                VE_LOG
+                    ( "dependencies found for %s, update will wait for the AP to finish processing them"
+                    , m_result.asset.Path().c_str());
+
+                m_waitTimeStamp = AZStd::chrono::system_clock::now();
+                m_waitLogTimeStamp = AZStd::chrono::system_clock::time_point{};
+                m_modifyState = ModifyState::WaitingForDependencyProcessing;
+            }
+            else
+            {
+                m_modifyState = ModifyState::StartModification;
+            }
         }
-            
+
         void Modifier::GatherDependencies()
         {
             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");
 
+            LoadAsset();
             bool anyFailures = false;
 
             if (m_result.asset.Get() && m_result.asset.Mod()->GetGraphData())
@@ -101,7 +204,7 @@ namespace ScriptCanvasEditor
                     , nullptr))
                 {
                     anyFailures = true;
-                        VE_LOG("Modifier: ERROR - Failed to gather dependencies from graph data: %s"
+                    VE_LOG("Modifier: ERROR - Failed to gather dependencies from graph data: %s"
                         , m_result.asset.Path().c_str())
                 }
             }
@@ -111,16 +214,40 @@ namespace ScriptCanvasEditor
                 VE_LOG("Modifier: ERROR - Failed to load asset %s for modification, even though it scanned properly"
                     , m_result.asset.Path().c_str());
             }
-            
+
             ModelNotificationsBus::Broadcast
                 ( &ModelNotificationsTraits::OnUpgradeDependenciesGathered
                 , m_result.asset
                 , anyFailures ? Result::Failure : Result::Success);
+        }
 
-            ReleaseCurrentAsset();
+        size_t Modifier::GetCurrentIndex() const
+        {
+            return m_state == State::GatheringDependencies
+                ? m_assetIndex
+                : m_dependencyOrderedAssetIndicies[m_assetIndex];
+        }
 
-            // Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
-            AZ::Data::AssetManager::Instance().DispatchEvents();
+        const AZStd::unordered_set<size_t>* Modifier::GetDependencies(size_t index) const
+        {
+            auto iter = m_dependencies.find(index);
+            return iter != m_dependencies.end() ? &iter->second : nullptr;
+        }
+
+        AZStd::unordered_set<size_t>& 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<size_t>()).first;
+            }
+
+            return iter->second;
+        }
+
+        const ModificationResults& Modifier::GetResult() const
+        {
+            return m_results;
         }
 
         void Modifier::LoadAsset()
@@ -144,7 +271,7 @@ namespace ScriptCanvasEditor
             }
             else if (m_result.asset.Describe() != result.asset.Describe())
             {
-                ReportModificationError("Received modifiction complete notification for different result");
+                ReportModificationError("Received modification complete notification for different result");
             }
             else
             {
@@ -154,9 +281,6 @@ namespace ScriptCanvasEditor
 
         void Modifier::ModifyCurrentAsset()
         {
-            m_result = {};
-            m_result.asset = m_assets[GetCurrentIndex()];
-            ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeModificationBegin, m_config, m_result.asset);
             LoadAsset();
 
             if (m_result.asset.IsGraphValid())
@@ -171,34 +295,55 @@ namespace ScriptCanvasEditor
             }
         }
 
-        void Modifier::ModifyNextAsset()
+        void Modifier::InitializeResult()
         {
-            ModelNotificationsBus::Broadcast
-                ( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, m_result.asset, m_result);
+            m_result = {};
+
+            if (m_assetIndex != m_assets.size())
+            {
+                m_result.asset = m_assets[GetCurrentIndex()];
+                CompleteDescriptionInPlace(m_result.asset);
+                m_attemptedAssets.insert(m_result.asset.Id());
+            }
+        }
+
+        void Modifier::NextAsset()
+        {
+            ++m_assetIndex;
+            InitializeResult();
+        }
+
+        void Modifier::NextModification()
+        {
+            ModelNotificationsBus::Broadcast( &ModelNotificationsTraits::OnUpgradeModificationEnd, m_config, m_result.asset, m_result);
             ModificationNotificationsBus::Handler::BusDisconnect();
+            NextAsset();
+            m_fileSaveResult = {};
             m_modifyState = ModifyState::Idle;
-            ReleaseCurrentAsset();
-            ++m_assetIndex;
-            m_result = {};
         }
 
         void Modifier::ReleaseCurrentAsset()
         {
             m_result.asset = m_result.asset.Describe();
+            // Flush asset database events to ensure no asset references are held by closures queued on Ebuses.
+            AZ::Data::AssetManager::Instance().DispatchEvents();
         }
 
         void Modifier::ReportModificationError(AZStd::string_view report)
         {
             m_result.errorMessage = report;
             m_results.m_failures.push_back({ m_result.asset.Describe(), report });
-            ModifyNextAsset();
+            m_assetsFailedByAP.insert(m_result.asset.Id());
+            NextModification();
         }
 
         void Modifier::ReportModificationSuccess()
         {
-            m_result.asset = m_result.asset.Describe();
+            // \note DO NOT put asset into the m_assetsCompletedByAP here. That can only be done when the message is received by the AP
             m_results.m_successes.push_back({ m_result.asset.Describe(), {} });
-            ModifyNextAsset();
+            AzFramework::AssetSystemRequestBus::Broadcast(
+                &AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetByUuid, m_result.asset.Id());
+            NextModification();
         }
 
         void Modifier::ReportSaveResult()
@@ -214,9 +359,6 @@ namespace ScriptCanvasEditor
             {
                 ReportModificationError(m_fileSaveResult.fileSaveError);
             }
-
-            m_fileSaveResult = {};
-            m_modifyState = ModifyState::Idle;
         }
 
         void Modifier::OnFileSaveComplete(const FileSaveResult& result)
@@ -316,49 +458,87 @@ namespace ScriptCanvasEditor
 
                 m_assetIndex = 0;
                 m_state = State::ModifyingGraphs;
+                InitializeResult();
             }
             else
             {
                 GatherDependencies();
-                ReleaseCurrentAsset();
-                ++m_assetIndex;
+                NextAsset();
             }
         }
 
         void Modifier::TickUpdateGraph()
         {
-            if (m_assetIndex == m_assets.size())
+            AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
+
+            switch (m_modifyState)
             {
-                VE_LOG("Modifier: Complete.");
-                AZ::SystemTickBus::Handler::BusDisconnect();
+            case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::Idle:
+                if (m_assetIndex == m_assets.size())
+                {
+                    VE_LOG("Modifier: Complete.");
+                    AZ::SystemTickBus::Handler::BusDisconnect();
 
-                if (m_onComplete)
+                    if (m_onComplete)
+                    {
+                        m_onComplete();
+                    }
+                }
+                else
                 {
-                    m_onComplete();
+                    CheckDependencies();
                 }
+                break;
+            case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::WaitingForDependencyProcessing:
+                WaitForDependencies();
+                break;
+            case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::StartModification:
+                ModifyCurrentAsset();
+                break;
+            case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::ReportResult:
+                ReportSaveResult();
+                break;
+            default:
+                break;
             }
-            else
+        }
+
+        void Modifier::WaitForDependencies()
+        {
+            const AZ::s32 LogPeriodSeconds = 5;
+
+            ProcessNotifications();
+
+            auto dependencies = GetDependencies(GetCurrentIndex());
+            if (dependencies == nullptr || dependencies->empty() || AllDependenciesCleared(*dependencies))
+            {
+                m_modifyState = ModifyState::StartModification;
+            }
+            else if (AnyDependenciesFailed(*dependencies))
+            {
+                ReportModificationError("A required dependency failed to update, graph cannot update.");
+            }
+            else if (AZStd::chrono::seconds(CalculateRemainingWaitTime(*dependencies)).count() < 0)
+            {
+                ReportModificationError("Dependency update time has taken too long, aborting modification.");
+            }
+            else if (AZStd::chrono::seconds(AZStd::chrono::system_clock::now() - m_waitLogTimeStamp).count() > LogPeriodSeconds)
             {
-                AZStd::lock_guard<AZStd::recursive_mutex> lock(m_mutex);
+                m_waitLogTimeStamp = AZStd::chrono::system_clock::now();
 
-                switch (m_modifyState)
-                {
-                case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::Idle:
-                    ModifyCurrentAsset();
-                    break;
-                case ScriptCanvasEditor::VersionExplorer::Modifier::ModifyState::ReportResult:
-                    ReportSaveResult();
-                    break;
-                default:
-                    break;
-                }
+                AZ_TracePrintf
+                    ( ScriptCanvas::k_VersionExplorerWindow.data()
+                    , "Waiting for dependencies for %d more seconds: %s"
+                    , AZStd::chrono::seconds(CalculateRemainingWaitTime(*dependencies)).count()
+                    , m_result.asset.Path().c_str());
+
+                ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeDependencyWaitInterval, m_result.asset);
             }
         }
 
         const AZStd::unordered_set<size_t>* Modifier::Sorter::GetDependencies(size_t index) const
         {
-            auto iter = modifier->m_dependencies.find(index);
-            return iter != modifier->m_dependencies.end() ? &iter->second : nullptr;
+            return modifier->GetDependencies(index);
         }
 
         void Modifier::Sorter::Sort()
@@ -379,7 +559,7 @@ namespace ScriptCanvasEditor
             if (markedTemporary.contains(index))
             {
                 AZ_Error
-                    (ScriptCanvas::k_VersionExplorerWindow.data()
+                    ( ScriptCanvas::k_VersionExplorerWindow.data()
                     , false
                     , "Modifier: Dependency sort has failed during, circular dependency detected for Asset: %s"
                     , modifier->m_result.asset.Path().c_str());

+ 39 - 5
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h

@@ -9,17 +9,23 @@
 #pragma once
 
 #include <AzCore/Component/TickBus.h>
+#include <AzFramework/Asset/AssetSystemBus.h>
 #include <Editor/View/Windows/Tools/UpgradeTool/FileSaver.h>
 #include <Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h>
 #include <ScriptCanvas/Core/Core.h>
 
+// probably not needed if using the asset system bus
+#include <AzToolsFramework/API/EditorAssetSystemAPI.h>
+
 namespace ScriptCanvasEditor
 {
     namespace VersionExplorer
     {
-        class Modifier
-            : private AZ::SystemTickBus::Handler
-            , private ModificationNotificationsBus::Handler
+        class Modifier final
+            : public AZ::SystemTickBus::Handler
+            , public ModificationNotificationsBus::Handler
+            , public AzToolsFramework::AssetSystemBus::Handler
+            , public AzFramework::AssetSystemInfoBus::Handler
         {
         public:
             AZ_CLASS_ALLOCATOR(Modifier, AZ::SystemAllocator, 0);
@@ -29,6 +35,8 @@ namespace ScriptCanvasEditor
                 , AZStd::vector<SourceHandle>&& assets
                 , AZStd::function<void()> onComplete);
 
+            virtual ~Modifier();
+
             const ModificationResults& GetResult() const;
             ModificationResults&& TakeResult();
 
@@ -56,6 +64,8 @@ namespace ScriptCanvasEditor
             enum class ModifyState
             {
                 Idle,
+                WaitingForDependencyProcessing,
+                StartModification,
                 InProgress,
                 Saving,
                 ReportResult
@@ -82,13 +92,27 @@ namespace ScriptCanvasEditor
             ModificationResults m_results;
             AZStd::unique_ptr<FileSaver> m_fileSaver;
             FileSaveResult m_fileSaveResult;
+            AZStd::unordered_set<AZ::Uuid> m_attemptedAssets;
+            AZStd::unordered_set<AZ::Uuid> m_assetsCompletedByAP;
+            AZStd::unordered_set<AZ::Uuid> m_assetsFailedByAP;
+            AZStd::chrono::system_clock::time_point m_waitLogTimeStamp;
+            AZStd::chrono::system_clock::time_point m_waitTimeStamp;
+            AZStd::unordered_set<AZStd::string> m_successNotifications;
+            AZStd::unordered_set<AZStd::string> m_failureNotifications;
 
-            size_t GetCurrentIndex() const;
+            bool AllDependenciesCleared(const AZStd::unordered_set<size_t>& dependencies) const;
+            bool AnyDependenciesFailed(const AZStd::unordered_set<size_t>& dependencies) const;
+            AZStd::sys_time_t CalculateRemainingWaitTime(const AZStd::unordered_set<size_t>& dependencies) const;
+            void CheckDependencies();
             void GatherDependencies();
+            size_t GetCurrentIndex() const;
+            const AZStd::unordered_set<size_t>* GetDependencies(size_t index) const;
             AZStd::unordered_set<size_t>& GetOrCreateDependencyIndexSet();
+            void InitializeResult();
             void LoadAsset();
             void ModifyCurrentAsset();
-            void ModifyNextAsset();
+            void NextAsset();
+            void NextModification();
             void ModificationComplete(const ModificationResult& result) override;
             void ReleaseCurrentAsset();
             void ReportModificationError(AZStd::string_view report);
@@ -96,10 +120,20 @@ namespace ScriptCanvasEditor
             void ReportSaveResult();
             void SaveModifiedGraph(const ModificationResult& result);
             void SortGraphsByDependencies();
+
+
+            /// use all this to track the success of dependencies
+            void SourceFileChanged(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
+            void SourceFileFailed(AZStd::string relativePath, AZStd::string scanFolder, AZ::Uuid fileAssetId) override;
+            void AssetCompilationSuccess(const AZStd::string& assetPath) override;
+            void AssetCompilationFailed(const AZStd::string& assetPath) override;
+            void ProcessNotifications();
+
             void OnFileSaveComplete(const FileSaveResult& result);
             void OnSystemTick() override;
             void TickGatherDependencies();
             void TickUpdateGraph();
+            void WaitForDependencies();
         };
     }
 }

+ 3 - 1
Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp

@@ -81,7 +81,9 @@ namespace ScriptCanvasEditor
 
         void Scanner::FilterAsset(SourceHandle asset)
         {
-            if (m_config.filter && m_config.filter(asset) == ScanConfiguration::Filter::Exclude)
+            AZStd::string name = asset.Path().c_str();
+
+            if ((m_config.filter && m_config.filter(asset) == ScanConfiguration::Filter::Exclude) || !name.contains("LY_SC_UnitTest_FunctionContainer"))
             {
                 VE_LOG("Scanner: Excluded: %s ", ModCurrentAsset().Path().c_str());
                 m_result.m_filteredAssets.push_back(ModCurrentAsset().Describe());

+ 1 - 0
Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.cpp

@@ -15,6 +15,7 @@ namespace ScriptCanvas
         AZ_CVAR(bool, g_disableParseOnGraphValidation, false, {}, AZ::ConsoleFunctorFlags::Null, "In case parsing the graph is interfering with opening a graph, disable parsing on validation");
         AZ_CVAR(bool, g_printAbstractCodeModel, true, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing for debug purposes.");
         AZ_CVAR(bool, g_printAbstractCodeModelAtPrefabTime, false, {}, AZ::ConsoleFunctorFlags::Null, "Print out the Abstract Code Model at the end of parsing (at prefab time) for debug purposes.");
+        AZ_CVAR(bool, g_processingErrorsForUnitTestsEnabled, false, {}, AZ::ConsoleFunctorFlags::Null, "Enable AP processing errors on parse failure for unit tests.");
         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.");
 

+ 1 - 0
Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h

@@ -245,6 +245,7 @@ namespace ScriptCanvas
         AZ_CVAR_EXTERNED(bool, g_disableParseOnGraphValidation);
         AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModel);
         AZ_CVAR_EXTERNED(bool, g_printAbstractCodeModelAtPrefabTime);
+        AZ_CVAR_EXTERNED(bool, g_processingErrorsForUnitTestsEnabled);
         AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFile);
         AZ_CVAR_EXTERNED(bool, g_saveRawTranslationOuputToFileAtPrefabTime);