diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 6c10726e13..ee539aa5fa 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -3435,25 +3435,20 @@ namespace ScriptCanvasEditor void MainWindow::RunUpgradeTool() { - // \todo, restore this behavior, post modification step - - /* auto versionExplorer = aznew VersionExplorer::Controller(this); versionExplorer->exec(); - - + // update and fix this // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - - // If there are graphs that need manual correction, show the helper - if (assetsThatNeedManualInspection > 0) - { - UpgradeHelper* upgradeHelper = new UpgradeHelper(this); - upgradeHelper->show(); - } - */ +// size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); +// // If there are graphs that need manual correction, show the helper +// if (assetsThatNeedManualInspection > 0) +// { +// UpgradeHelper* upgradeHelper = new UpgradeHelper(this); +// upgradeHelper->show(); +// } + delete versionExplorer; } void MainWindow::OnShowValidationErrors() 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 8eae0e1bd0..c8353b1d25 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.cpp @@ -54,7 +54,7 @@ namespace ScriptCanvasEditor m_view->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); connect(m_view->scanButton, &QPushButton::pressed, this, &Controller::OnScanButtonPress); connect(m_view->closeButton, &QPushButton::pressed, this, &Controller::OnCloseButtonPress); - connect(m_view->upgradeAllButton, &QPushButton::pressed, this, &Controller::OnUpgradeAllButtonPress); + connect(m_view->upgradeAllButton, &QPushButton::pressed, this, &Controller::OnUpgradeButtonPress); m_view->progressBar->setValue(0); m_view->progressBar->setVisible(false); @@ -130,7 +130,7 @@ namespace ScriptCanvasEditor void Controller::OnScanBegin(size_t assetCount) { - m_currentAssetRowIndex = 0; + m_handledAssetCount = 0; m_view->tableWidget->setRowCount(0); m_view->progressBar->setVisible(true); m_view->progressBar->setRange(0, aznumeric_cast(assetCount)); @@ -138,6 +138,10 @@ namespace ScriptCanvasEditor m_view->scanButton->setEnabled(false); m_view->upgradeAllButton->setEnabled(false); m_view->onlyShowOutdated->setEnabled(false); + + QString spinnerText = QStringLiteral("Scan in progress - gathering graphs that can be updated"); + m_view->spinner->SetText(spinnerText); + SetSpinnerIsBusy(true); } void Controller::OnScanComplete(const ScanResult& result) @@ -161,6 +165,7 @@ namespace ScriptCanvasEditor , result.m_filteredAssets.size())); m_view->spinner->SetText(spinnerText); + SetSpinnerIsBusy(false); m_view->progressBar->setVisible(false); if (!result.m_unfiltered.empty()) @@ -176,17 +181,17 @@ namespace ScriptCanvasEditor void Controller::OnScannedGraph(const AZ::Data::AssetInfo& assetInfo, Filtered filtered) { - m_view->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); + m_view->tableWidget->insertRow(m_handledAssetCount); QTableWidgetItem* rowName = new QTableWidgetItem(tr(assetInfo.m_relativePath.c_str())); - m_view->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); + m_view->tableWidget->setItem(m_handledAssetCount, static_cast(ColumnAsset), rowName); + SetRowSucceeded(m_handledAssetCount); if (filtered == Filtered::No) { QPushButton* rowGoToButton = new QPushButton(this); rowGoToButton->setText("Upgrade"); rowGoToButton->setEnabled(false); - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); + SetRowBusy(m_handledAssetCount); // \\ todo restore this // connect(rowGoToButton, &QPushButton::clicked, [this, rowGoToButton, assetInfo] { // @@ -200,8 +205,7 @@ namespace ScriptCanvasEditor // // }); - m_view->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_view->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); + m_view->tableWidget->setCellWidget(m_handledAssetCount, static_cast(ColumnAction), rowGoToButton); } char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; @@ -234,23 +238,24 @@ namespace ScriptCanvasEditor AzQtComponents::ShowFileOnDesktop(absolutePath); }); - m_view->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); + m_view->tableWidget->setCellWidget(m_handledAssetCount, static_cast(ColumnBrowse), browseButton); OnScannedGraphResult(assetInfo); } void Controller::OnScannedGraphResult([[maybe_unused]] const AZ::Data::AssetInfo& info) { - m_view->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - ++m_currentAssetRowIndex; + m_view->progressBar->setValue(aznumeric_cast(m_handledAssetCount)); + ++m_handledAssetCount; AddLogEntries(); } void Controller::OnScanLoadFailure(const AZ::Data::AssetInfo& info) { - m_view->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); + m_view->tableWidget->insertRow(m_handledAssetCount); QTableWidgetItem* rowName = new QTableWidgetItem ( tr(AZStd::string::format("Load Error: %s", info.m_relativePath.c_str()).c_str())); - m_view->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); + m_view->tableWidget->setItem(m_handledAssetCount, static_cast(ColumnAsset), rowName); + SetRowFailed(m_handledAssetCount, "Load failed"); OnScannedGraphResult(info); } @@ -259,7 +264,7 @@ namespace ScriptCanvasEditor OnScannedGraph(info, Filtered::No); } - void Controller::OnUpgradeAllButtonPress() + void Controller::OnUpgradeButtonPress() { auto simpleUpdate = [this](AZ::Data::Asset asset) { @@ -321,32 +326,167 @@ namespace ScriptCanvasEditor ModelRequestsBus::Broadcast(&ModelRequestsTraits::Modify, config); } - void Controller::OnUpgradeAllBegin() + void Controller::OnUpgradeBegin + ( const ModifyConfiguration& config + , [[maybe_unused]] const AZStd::vector& assets) { - m_currentAssetRowIndex = 0; - m_view->tableWidget->setRowCount(0); + for (int row = 0; row < m_view->tableWidget->rowCount(); ++row) + { + if (QPushButton* button = qobject_cast(m_view->tableWidget->cellWidget(row, ColumnAction))) + { + button->setEnabled(false); + SetRowBusy(row); + } + } + + QString spinnerText = QStringLiteral("Upgrade in progress - "); + if (config.modifySingleAsset) + { + spinnerText.append(" single graph"); + } + else + { + spinnerText.append(" all scanned graphs"); + } + + m_view->spinner->SetText(spinnerText); + SetSpinnerIsBusy(true); + } + + void Controller::SetSpinnerIsBusy(bool isBusy) + { + m_view->spinner->SetIsBusy(isBusy); + m_view->spinner->SetBusyIconSize(16); + } + + void Controller::OnUpgradeComplete() + { + SetSpinnerIsBusy(false); + } + + void Controller::OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result) + { + QList items = m_view->tableWidget->findItems(info.m_relativePath.c_str(), Qt::MatchFlag::MatchExactly); + if (!items.isEmpty()) + { + for (auto* item : items) + { + int row = item->row(); + + if (result == Result::Success) + { + SetRowSucceeded(row); + } + else + { + SetRowFailed(row, ""); + } + } + } + m_view->progressBar->setVisible(true); + ++m_handledAssetCount; + m_view->progressBar->setValue(m_handledAssetCount); + } + + void Controller::OnUpgradeDependencySortBegin + ( [[maybe_unused]] const ModifyConfiguration& config + , const AZStd::vector& assets) + { + m_handledAssetCount = 0; + m_view->progressBar->setVisible(true); + m_view->progressBar->setRange(0, aznumeric_caster(assets.size())); m_view->progressBar->setValue(0); m_view->scanButton->setEnabled(false); m_view->upgradeAllButton->setEnabled(false); m_view->onlyShowOutdated->setEnabled(false); + + for (int row = 0; row != m_view->tableWidget->rowCount(); ++row) + { + if (QPushButton* button = qobject_cast(m_view->tableWidget->cellWidget(row, ColumnAction))) + { + button->setEnabled(false); + SetRowBusy(row); + } + } + + QString spinnerText = QStringLiteral("Upgrade in progress - gathering dependencies for the scanned graphs"); + m_view->spinner->SetText(spinnerText); + SetSpinnerIsBusy(true); } - void Controller::OnUpgradeAllComplete() - { - - } - - void Controller::OnUpgradeAllDependencySortBegin() - { - - } - - void Controller::OnUpgradeAllDependencySortEnd - ( const AZStd::vector& sortedAssets + void Controller::OnUpgradeDependencySortEnd + ( [[maybe_unused]] const ModifyConfiguration& config + , const AZStd::vector& assets , [[maybe_unused]] const AZStd::vector& sortedOrder) { - m_view->progressBar->setRange(0, aznumeric_cast(sortedAssets.size())); + m_handledAssetCount = 0; + m_view->progressBar->setRange(0, aznumeric_caster(assets.size())); + m_view->progressBar->setValue(0); + m_view->progressBar->setVisible(true); + + for (int row = 0; row != m_view->tableWidget->rowCount(); ++row) + { + if (QPushButton* button = qobject_cast(m_view->tableWidget->cellWidget(row, ColumnAction))) + { + button->setEnabled(false); + SetRowPending(row); + } + } + + QString spinnerText = QStringLiteral("Upgrade in progress - gathering dependencies is complete"); + m_view->spinner->SetText(spinnerText); + SetSpinnerIsBusy(false); + } + + void Controller::SetRowBusy(int index) + { + if (index >= m_view->tableWidget->rowCount()) + { + return; + } + + AzQtComponents::StyledBusyLabel* busy = new AzQtComponents::StyledBusyLabel(this); + busy->SetBusyIconSize(16); + m_view->tableWidget->setCellWidget(index, ColumnStatus, busy); + } + + void Controller::SetRowFailed(int index, AZStd::string_view message) + { + if (index >= m_view->tableWidget->rowCount()) + { + return; + } + + QToolButton* doneButton = new QToolButton(this); + doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); + doneButton->setToolTip(message.data()); + m_view->tableWidget->setCellWidget(index, ColumnStatus, doneButton); + } + + void Controller::SetRowPending(int index) + { + m_view->tableWidget->removeCellWidget(index, ColumnStatus); + } + + void Controller::SetRowsBusy() + { + for (int i = 0; i != m_view->tableWidget->rowCount(); ++i) + { + SetRowBusy(i); + } + } + + void Controller::SetRowSucceeded(int index) + { + if (index >= m_view->tableWidget->rowCount()) + { + return; + } + + QToolButton* doneButton = new QToolButton(this); + doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); + m_view->tableWidget->setCellWidget(index, ColumnStatus, doneButton); } } } 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 e2f00fe6f3..f99aaf5466 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Controller.h @@ -58,13 +58,13 @@ namespace ScriptCanvasEditor static constexpr int ColumnStatus = 3; AZStd::unique_ptr m_view; - size_t m_currentAssetRowIndex = 0; + int m_handledAssetCount = 0; void AddLogEntries(); void OnCloseButtonPress(); void OnScanButtonPress(); - void OnUpgradeAllButtonPress(); + void OnUpgradeButtonPress(); void OnScanBegin(size_t assetCount) override; void OnScanComplete(const ScanResult& result) override; @@ -74,13 +74,25 @@ namespace ScriptCanvasEditor enum class Filtered { No, Yes }; void OnScannedGraph(const AZ::Data::AssetInfo& info, Filtered filtered); void OnScannedGraphResult(const AZ::Data::AssetInfo& info); - - void OnUpgradeAllBegin() override; - void OnUpgradeAllComplete() override; - void OnUpgradeAllDependencySortBegin() override; - void OnUpgradeAllDependencySortEnd - ( const AZStd::vector& sortedAssets + + // for single operation UI updates, just check the assets size, or note it on the request + void OnUpgradeBegin(const ModifyConfiguration& config, const AZStd::vector& assets) override; + void OnUpgradeComplete() override; + void OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result) override; + void OnUpgradeDependencySortBegin + ( const ModifyConfiguration& config + , const AZStd::vector& assets) override; + void OnUpgradeDependencySortEnd + ( const ModifyConfiguration& config + , const AZStd::vector& assets , const AZStd::vector& sortedOrder) override; + + void SetSpinnerIsBusy(bool isBusy); + void SetRowBusy(int index); + void SetRowFailed(int index, AZStd::string_view message); + void SetRowPending(int index); + void SetRowsBusy(); + void SetRowSucceeded(int index); }; } } 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 09ad2b01c1..86e1b47b18 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h @@ -17,8 +17,8 @@ namespace ScriptCanvasEditor struct ModifyConfiguration { AZStd::function)> modification; + bool modifySingleAsset = false; bool backupGraphBeforeModification = false; - // disabling this can be acceptable, but be careful bool successfulDependencyUpgradeRequired = true; }; @@ -50,6 +50,12 @@ namespace ScriptCanvasEditor AZStd::vector m_loadErrors; }; + enum Result + { + Failure, + Success + }; + class ModelNotificationsTraits : public AZ::EBusTraits { @@ -60,11 +66,17 @@ namespace ScriptCanvasEditor virtual void OnScanLoadFailure(const AZ::Data::AssetInfo& info) = 0; virtual void OnScanUnFilteredGraph(const AZ::Data::AssetInfo& info) = 0; - virtual void OnUpgradeAllBegin() = 0; - virtual void OnUpgradeAllComplete() = 0; - virtual void OnUpgradeAllDependencySortBegin() = 0; - virtual void OnUpgradeAllDependencySortEnd - ( const AZStd::vector& assets + virtual void OnUpgradeBegin(const ModifyConfiguration& config, const AZStd::vector& assets) = 0; + virtual void OnUpgradeComplete() = 0; + // virtual void OnUpgradeModificationBegin(const ModifyConfiguration& config) = 0; + // virtual void OnUpgradeModification(const ModifyConfiguration& config, const AZ::Data::AssetInfo& info, Result result) = 0; + virtual void OnUpgradeDependenciesGathered(const AZ::Data::AssetInfo& info, Result result) = 0; + virtual void OnUpgradeDependencySortBegin + ( const ModifyConfiguration& config + , const AZStd::vector& assets) = 0; + virtual void OnUpgradeDependencySortEnd + ( const ModifyConfiguration& config + , 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 1723b0f8ff..5656d6cf6d 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp @@ -30,7 +30,7 @@ namespace ScriptCanvasEditor , m_assets(assets) , m_onComplete(onComplete) { - ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeAllBegin); + ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeBegin, modification, m_assets); AZ::SystemTickBus::Handler::BusConnect(); } @@ -58,52 +58,64 @@ namespace ScriptCanvasEditor AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); AZ_Assert(serializeContext, "SerializeContext is required to enumerate dependent assets in the ScriptCanvas file"); + bool anyFailures = false; 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; - } - auto graphData = asset.GetAs()->GetScriptCanvasGraph()->GetGraphData(); - - auto dependencyGrabber = [this] - ( void* instancePointer - , const AZ::SerializeContext::ClassData* classData - , [[maybe_unused]] const AZ::SerializeContext::ClassElement* classElement) + if (asset + && asset.GetAs() + && asset.GetAs()->GetScriptCanvasGraph() + && asset.GetAs()->GetScriptCanvasGraph()->GetGraphData()) { - auto azTypeId = classData->m_azRtti->GetTypeId(); - if (azTypeId == azrtti_typeid>()) + auto graphData = asset.GetAs()->GetScriptCanvasGraph()->GetGraphData(); + + auto dependencyGrabber = [this] + ( void* instancePointer + , const AZ::SerializeContext::ClassData* classData + , [[maybe_unused]] const AZ::SerializeContext::ClassElement* classElement) { - const auto* subgraphAsset = reinterpret_cast*>(instancePointer); - if (subgraphAsset->GetId().IsValid()) + if (auto azTypeId = classData->m_azRtti->GetTypeId(); + azTypeId == azrtti_typeid>()) { - if (auto iter = m_assetInfoIndexById.find(subgraphAsset->GetId().m_guid); iter != m_assetInfoIndexById.end()) + const auto* subgraphAsset = + reinterpret_cast*>(instancePointer); + if (subgraphAsset->GetId().IsValid()) { - GetOrCreateDependencyIndexSet().insert(iter->second); - } - else - { - VE_LOG("Modifier: Dependency found that was not picked up by the scanner: %s" - , subgraphAsset->GetId().ToString().c_str()); + if (auto iter = m_assetInfoIndexById.find(subgraphAsset->GetId().m_guid); iter != m_assetInfoIndexById.end()) + { + // insert the index of the dependency into the set that belongs to this asset + GetOrCreateDependencyIndexSet().insert(iter->second); + } } } - } - // always continue, make note of the script canvas dependencies - return true; - }; + // always continue, make note of the script canvas dependencies + return true; + }; - AZ_Verify(serializeContext->EnumerateInstanceConst - ( graphData - , azrtti_typeid() - , dependencyGrabber - , {} - , AZ::SerializeContext::ENUM_ACCESS_FOR_READ - , nullptr - , nullptr), "Failed to gather dependencies from graph data"); + if (!serializeContext->EnumerateInstanceConst + ( graphData + , azrtti_typeid() + , dependencyGrabber + , {} + , AZ::SerializeContext::ENUM_ACCESS_FOR_READ + , nullptr + , nullptr)) + { + anyFailures = true; + VE_LOG("Modifier: ERROR - Failed to gather dependencies from graph data: %s" + , GetCurrentAsset().m_relativePath.c_str()) + } + } + else + { + anyFailures = true; + VE_LOG("Modifier: ERROR - Failed to load asset %s for modification, even though it scanned properly" + , GetCurrentAsset().m_relativePath.c_str()); + } + + ModelNotificationsBus::Broadcast + ( &ModelNotificationsTraits::OnUpgradeDependenciesGathered + , GetCurrentAsset() + , anyFailures ? Result::Failure : Result::Success); // Flush asset database events to ensure no asset references are held by closures queued on Ebuses. AZ::Data::AssetManager::Instance().DispatchEvents(); @@ -154,14 +166,6 @@ namespace ScriptCanvasEditor { 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) @@ -210,7 +214,7 @@ namespace ScriptCanvasEditor { if (m_config.successfulDependencyUpgradeRequired) { - ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeAllDependencySortBegin); + ModelNotificationsBus::Broadcast(&ModelNotificationsTraits::OnUpgradeDependencySortBegin, m_config, m_assets); m_assetInfoIndexById.reserve(m_assets.size()); for (size_t index = 0; index != m_assets.size(); ++index) @@ -226,16 +230,24 @@ namespace ScriptCanvasEditor { m_dependencyOrderedAssetIndicies.push_back(index); } + + // go straight into ModifyinGraphs + m_assetIndex = m_assets.size(); } } if (m_assetIndex == m_assets.size()) { - SortGraphsByDependencies(); - ModelNotificationsBus::Broadcast - ( &ModelNotificationsTraits::OnUpgradeAllDependencySortEnd - , m_assets - , m_dependencyOrderedAssetIndicies); + if (m_config.successfulDependencyUpgradeRequired) + { + SortGraphsByDependencies(); + ModelNotificationsBus::Broadcast + ( &ModelNotificationsTraits::OnUpgradeDependencySortEnd + , m_config + , m_assets + , m_dependencyOrderedAssetIndicies); + } + m_assetIndex = 0; m_state = State::ModifyingGraphs; } @@ -245,5 +257,11 @@ namespace ScriptCanvasEditor ++m_assetIndex; } } + + void Modifier::TickUpdateGraph() + { + + } + } }