From b6eb9123e545052cd2f35f8d2d21db22b9dcf2b5 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Fri, 10 Sep 2021 19:38:28 -0700 Subject: [PATCH] version explorer refactor wip Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Editor/View/Windows/MainWindow.cpp | 4 +- .../Code/Editor/View/Windows/MainWindow.h | 2 +- .../Windows/Tools/UpgradeTool/FileSaver.cpp | 980 +--------- .../Windows/Tools/UpgradeTool/FileSaver.h | 167 +- .../View/Windows/Tools/UpgradeTool/Model.cpp | 25 + .../View/Windows/Tools/UpgradeTool/Model.h | 33 + .../Windows/Tools/UpgradeTool/ModelTraits.h | 31 + .../Windows/Tools/UpgradeTool/Modifier.cpp | 1005 +--------- .../View/Windows/Tools/UpgradeTool/Modifier.h | 154 +- .../Windows/Tools/UpgradeTool/Scanner.cpp | 1005 +--------- .../View/Windows/Tools/UpgradeTool/Scanner.h | 154 +- .../Tools/UpgradeTool/VersionExplorerLog.cpp | 1008 +--------- .../Tools/UpgradeTool/VersionExplorerLog.h | 172 +- .../Tools/UpgradeTool/VersionExplorerTraits.h | 22 - .../View/Windows/Tools/UpgradeTool/View.cpp | 1735 ++++++++--------- .../View/Windows/Tools/UpgradeTool/View.h | 220 +-- .../View/Windows/Tools/UpgradeTool/View.ui | 4 +- .../Windows/Tools/UpgradeTool/ViewTraits.h | 26 + .../Code/scriptcanvasgem_editor_files.cmake | 26 +- 19 files changed, 1154 insertions(+), 5619 deletions(-) create mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.cpp create mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.h create mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h delete mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerTraits.h create mode 100644 Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ViewTraits.h diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp index 856cceb508..33a58c18a7 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.cpp @@ -134,7 +134,7 @@ #include #include #include -#include +#include #include @@ -3436,7 +3436,7 @@ namespace ScriptCanvasEditor void MainWindow::RunUpgradeTool() { - VersionExplorer* versionExplorer = aznew VersionExplorer(this); + auto versionExplorer = aznew VersionExplorer::View(this); versionExplorer->exec(); // Manual correction diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h index ed00254677..54557c3691 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/MainWindow.h @@ -51,7 +51,7 @@ #include -#include +#include #if SCRIPTCANVAS_EDITOR #include diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp index eb182ed291..7a7c4fe5a3 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp @@ -6,35 +6,10 @@ * */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -namespace VersionExplorerCpp +namespace FileSaverCpp { class FileEventHandler : public AZ::IO::FileIOEventBus::Handler @@ -67,957 +42,8 @@ namespace VersionExplorerCpp namespace ScriptCanvasEditor { - EditorKeepAlive::EditorKeepAlive() + namespace VersionExplorer { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) - { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); - } - } - - EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) - { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } - - VersionExplorer::VersionExplorer(QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent) - , m_ui(new Ui::VersionExplorer()) - { - m_ui->setupUi(this); - - m_ui->tableWidget->horizontalHeader()->setVisible(false); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_ui->tableWidget->setColumnWidth(3, 22); - - m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - - connect(m_ui->scanButton, &QPushButton::pressed, this, &VersionExplorer::OnScan); - connect(m_ui->closeButton, &QPushButton::pressed, this, &VersionExplorer::OnClose); - connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &VersionExplorer::OnUpgradeAll); - - m_ui->progressBar->setValue(0); - m_ui->progressBar->setVisible(false); - - m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); } - - VersionExplorer::~VersionExplorer() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } - - void VersionExplorer::Log(const char* format, ...) - { - if (m_ui->verbose->isChecked()) - { - char sBuffer[2048]; - va_list ArgList; - va_start(ArgList, format); - azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); - sBuffer[sizeof(sBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); - } - } - - void VersionExplorer::OnClose() - { - reject(); - } - - bool VersionExplorer::IsUpgrading() const - { - return m_inProgressAsset != m_assetsToUpgrade.end() && m_inProgress; - } - - void VersionExplorer::OnSystemTick() - { - switch (m_state) - { - case ProcessState::Scan: - - if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) - { - m_inProgress = true; - AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; - m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); - m_currentAsset.BlockUntilLoadComplete(); - if (m_currentAsset.IsReady()) - { - // The asset is ready, grab its info - m_inProgress = true; - InspectAsset(m_currentAsset, assetToUpgrade); - } - else - { - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem - ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - ++m_currentAssetRowIndex; - - Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_failedAssets; - ScanComplete(m_currentAsset); - } - } - break; - - case ProcessState::Upgrade: - { - AZStd::lock_guard lock(m_mutex); - if (m_upgradeComplete) - { - ++m_upgradeAssetIndex; - m_inProgress = false; - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - - if (m_scriptCanvasEntity) - { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } - - GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); - } - } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - m_settingsCache.reset(); - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } - - m_upgradeComplete = false; - } - - if (!IsUpgrading() && m_state == ProcessState::Upgrade) - { - AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); - // Make the backup - if (errorMessage.empty()) - { - Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); - QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); - spinner->SetIsBusy(true); - } - } - - // Upgrade the graph - UpgradeGraph(*m_inProgressAsset); - } - else - { - Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); - GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); - } - - } - break; - } - default: - break; - } - - FlushLogs(); - - AZ::Data::AssetManager::Instance().DispatchEvents(); - AZ::SystemTickBus::ExecuteQueuedEvents(); - } - - // Backup - - void VersionExplorer::OnUpgradeAll() - { - m_state = ProcessState::Upgrade; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - AZ::Interface::Get()->SetIsUpgrading(true); - AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); - m_inProgressAsset = m_assetsToUpgrade.begin(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - m_keepEditorAlive = AZStd::make_unique(); - } - - AZStd::string VersionExplorer::BackupGraph(const AZ::Data::Asset& asset) - { - if (!m_ui->makeBackupCheckbox->isChecked()) - { - // considered a success - return ""; - } - - QDateTime theTime = QDateTime::currentDateTime(); - QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); - - AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); - char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); - backupPath = backupPathCStr; - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) - { - if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); - return "Failed to create backup folder"; - } - } - - AZStd::string devRoot = "@devroot@"; - AZStd::string devAssets = "@devassets@"; - - char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); - - char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); - - AZStd::string relativePath = devAssetsCStr; - AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AZStd::string sourceFilePath; - - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); - if (sourceInfoFound) - { - AZStd::string assetPath; - AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - - sourceFilePath = assetPath; - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); - return "Failed to find source file"; - } - - devRoot = devRootCStr; - AzFramework::StringFunc::Path::Normalize(devRoot); - - relativePath = sourceFilePath; - AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AzFramework::StringFunc::Path::Normalize(relativePath); - AzFramework::StringFunc::Path::Normalize(backupPath); - - AZStd::string targetFilePath = backupPath; - targetFilePath += relativePath; - - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return "Failed to copy source file to backup location"; - } - - Log("VersionExplorer::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return ""; - } - - void VersionExplorer::UpgradeGraph(const AZ::Data::Asset& asset) - { - m_inProgress = true; - m_upgradeComplete = false; - Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); - m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - m_scriptCanvasEntity = nullptr; - - UpgradeNotifications::Bus::Handler::BusConnect(); - - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" - , azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "VersionExplorer::UpgradeGraph The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return; - } - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - m_scriptCanvasEntity = scriptCanvasEntity; - - graphComponent->UpgradeGraph - ( asset - , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate - , m_ui->verbose->isChecked()); - } - } - - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - } - - void VersionExplorer::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - if (!fullPathFound) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); - } - - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - this->OnSourceFileReleased(asset); - }); - streamer->QueueRequest(flushRequest); - } - - void VersionExplorer::OnSourceFileReleased(AZ::Data::Asset asset) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - m_tmpFileName.clear(); - AZStd::string tmpFileName; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. - // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); - return; - } - - bool tempSavedSucceeded = false; - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - if (fileStream.IsOpen()) - { - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasEditor::ScriptCanvasAssetHandler handler; - tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); - } - - fileStream.Close(); - } - - // attempt to remove temporary file no matter what - m_tmpFileName = tmpFileName; - if (!tempSavedSucceeded) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); - return; - } - - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - constexpr const size_t k_maxAttemps = 10; - - if (!info.IsReadOnly()) - { - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - if (m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - } - } - }); - } - - void VersionExplorer::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target - , size_t remainingAttempts) - { - VersionExplorerCpp::FileEventHandler fileEventHandler; - - if (remainingAttempts == 0) - { - // all attempts failed, give up - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); - GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); - } - else if (remainingAttempts == 2) - { - // before the final attempt, flush all caches - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); - streamer->SetRequestCompleteCallback(flushRequest - , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction( - [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - else - { - // the actual move attempt - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - m_tmpFileName.clear(); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - AZ::SystemTickBus::QueueFunction([this, asset]() - { - GraphUpgradeComplete(asset, OperationResult::Success, ""); - }); - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - } - } - - void VersionExplorer::GraphUpgradeComplete - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - AZStd::lock_guard lock(m_mutex); - m_upgradeComplete = true; - m_upgradeResult = result; - m_upgradeMessage = message; - m_upgradeAsset = asset; - - if (!m_tmpFileName.empty()) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - - if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) - { - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); - } - } - - if (m_upgradeResult == OperationResult::Failure) - { - AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); - } - - m_tmpFileName.clear(); - } - - void VersionExplorer::GraphUpgradeCompleteUIUpdate - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - QString text = asset.GetHint().c_str(); - QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); - - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); - - if (label->text().compare(assetName) == 0) - { - m_ui->tableWidget->removeCellWidget(row, ColumnAction); - m_ui->tableWidget->removeCellWidget(row, ColumnStatus); - - QToolButton* doneButton = new QToolButton(this); - doneButton->setToolTip("Upgrade complete"); - if (result == OperationResult::Success) - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); - } - else - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - doneButton->setToolTip(message.data()); - } - - m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); - } - } - } - } - - void VersionExplorer::FinalizeUpgrade() - { - Log("FinalizeUpgrade!"); - m_inProgress = false; - m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(true); - m_keepEditorAlive.reset(); - m_ui->progressBar->setVisible(false); - - // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - if (assetsThatNeedManualInspection > 0) - { - m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); - } - else - { - m_ui->spinner->SetText("Upgrade complete."); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); - m_settingsCache.reset(); - } - - // Scanning - - void VersionExplorer::OnScan() - { - m_assetsToUpgrade.clear(); - m_assetsToInspect.clear(); - m_ui->tableWidget->setRowCount(0); - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); - m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); - DoScan(); - } - - void VersionExplorer::DoScan() - { - m_state = ProcessState::Scan; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - - AZ::SystemTickBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - - if (!m_assetsToInspect.empty()) - { - m_discoveredAssets = m_assetsToInspect.size(); - m_failedAssets = 0; - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - m_ui->progressFrame->setVisible(true); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); - m_ui->progressBar->setValue(0); - - m_ui->spinner->SetIsBusy(true); - m_ui->spinner->SetBusyIconSize(32); - - m_ui->scanButton->setEnabled(false); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(false); - - m_inspectingAsset = m_assetsToInspect.begin(); - m_keepEditorAlive = AZStd::make_unique(); - } - } - - void VersionExplorer::BackupComplete() - { - m_currentAssetRowIndex = 0; - m_ui->progressBar->setValue(0); - DoScan(); - } - - void VersionExplorer::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) - { - Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - if (!scriptCanvasAsset) - { - Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); - return; - } - - scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); - bool forceUpgrade = m_ui->forceUpgrade->isChecked(); - ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - - - if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) - { - ScanComplete(asset); - Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); - return; - } - - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - - if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) - { - m_assetsToUpgrade.push_back(asset); - - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); - - QPushButton* rowGoToButton = new QPushButton(this); - rowGoToButton->setText("Upgrade"); - rowGoToButton->setEnabled(false); - - connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { - - AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { - // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda - UpgradeSingle(rowGoToButton, spinner, assetInfo); - }); - - AZ::SystemTickBus::ExecuteQueuedEvents(); - - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); - } - - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; - AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); - AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); - AZ::StringFunc::Path::Normalize(path); - - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - QByteArray assetNameUtf8 = asset.GetHint().c_str(); - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - - QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { - AzQtComponents::ShowFileOnDesktop(absolutePath); - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); - ScanComplete(asset); - ++m_inspectedAssets; - ++m_currentAssetRowIndex; - } - - void VersionExplorer::UpgradeSingle - ( QPushButton* rowGoToButton - , AzQtComponents::StyledBusyLabel* spinner - , AZ::Data::AssetInfo assetInfo) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - ( assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - - if (asset) - { - asset.BlockUntilLoadComplete(); - - if (asset.IsReady()) - { - AZ::Interface::Get()->SetIsUpgrading(true); - m_isUpgradingSingleGraph = true; - m_logs.clear(); - m_ui->textEdit->clear(); - spinner->SetIsBusy(true); - rowGoToButton->setEnabled(false); - - m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() - , [asset](const UpgradeAssets::value_type& assetToUpgrade) - { - return assetToUpgrade.GetId() == asset.GetId(); - }); - - m_state = ProcessState::Upgrade; - AZ::SystemTickBus::Handler::BusConnect(); - } - } - } - - void VersionExplorer::ScanComplete(const AZ::Data::Asset& asset) - { - Log("ScanComplete: %s", asset.GetHint().c_str()); - m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - m_ui->scanButton->setEnabled(true); - - m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); - FlushLogs(); - - if (m_inspectingAsset == m_assetsToInspect.end()) - { - AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - } - } - - void VersionExplorer::FinalizeScan() - { - Log("FinalizeScan()"); - - m_ui->spinner->SetIsBusy(false); - m_ui->onlyShowOutdated->setEnabled(true); - - // Enable all the Upgrade buttons - for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) - { - QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); - if (button) - { - button->setEnabled(true); - } - } - - QString spinnerText = QStringLiteral("Scan Complete"); - if (m_assetsToUpgrade.empty()) - { - spinnerText.append(" - No graphs require upgrade!"); - } - else - { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); - } - - - m_ui->spinner->SetText(spinnerText); - m_ui->progressBar->setVisible(false); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - - m_keepEditorAlive.reset(); - m_settingsCache.reset(); - m_state = ProcessState::Inactive; - } - - void VersionExplorer::FlushLogs() - { - if (m_logs.empty()) - { - return; - } - - const QTextCursor oldCursor = m_ui->textEdit->textCursor(); - QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); - - m_ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = m_ui->textEdit->textCursor(); - - while (!m_logs.empty()) - { - auto line = "\n" + m_logs.front(); - - m_logs.pop_front(); - - textCursor.insertText(line.c_str()); - } - - scrollBar->setValue(scrollBar->maximum()); - m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); - - } - - bool VersionExplorer::CaptureLogFromTraceBus(const char* window, const char* message) - { - if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) - { - return true; - } - - AZStd::string msg = message; - if (msg.ends_with("\n")) - { - msg = msg.substr(0, msg.size() - 1); - } - - m_logs.push_back(msg); - return m_ui->updateReportingOnly->isChecked(); - } - - bool VersionExplorer::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Error): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorer::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Warning): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorer::OnException(const char* message) - { - AZStd::string msg = AZStd::string::format("(Exception): %s", message); - return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - } - - bool VersionExplorer::OnPrintf(const char* window, const char* message) - { - return CaptureLogFromTraceBus(window, message); - } - - void VersionExplorer::closeEvent(QCloseEvent* event) - { - m_keepEditorAlive.reset(); - - AzQtComponents::StyledDialog::closeEvent(event); - } - -#include - } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.h index acb28a7dba..e1ab92acbc 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/FileSaver.h @@ -8,173 +8,16 @@ #pragma once -#if !defined(Q_MOC_RUN) -#include - -AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include - -#include #include -#include -#include -#include -#endif - -class QPushButton; - -namespace Ui -{ - class VersionExplorer; -} - -namespace AzQtComponents -{ - class StyledBusyLabel; -} - namespace ScriptCanvasEditor { - //! Scoped utility to set and restore the "ed_KeepEditorActive" CVar in order to allow - //! the upgrade tool to work even if the editor is not in the foreground - class EditorKeepAlive + namespace VersionExplorer { - public: - EditorKeepAlive(); - ~EditorKeepAlive(); - - private: - int m_keepEditorActive; - ICVar* m_edKeepEditorActive; - }; - - //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog - class VersionExplorer - : public AzQtComponents::StyledDialog - , private AZ::SystemTickBus::Handler - , private UpgradeNotifications::Bus::Handler - , private AZ::Debug::TraceMessageBus::Handler - { - Q_OBJECT - - public: - AZ_CLASS_ALLOCATOR(VersionExplorer, AZ::SystemAllocator, 0); - - explicit VersionExplorer(QWidget* parent = nullptr); - ~VersionExplorer(); - - private: - - static constexpr int ColumnAsset = 0; - static constexpr int ColumnAction = 1; - static constexpr int ColumnBrowse = 2; - static constexpr int ColumnStatus = 3; - - void OnScan(); - void OnClose(); - - enum class ProcessState + class FileSaver { - Inactive, - Backup, - Scan, - Upgrade, + public: + AZ_CLASS_ALLOCATOR(FileSaver, AZ::SystemAllocator, 0); }; - ProcessState m_state = ProcessState::Inactive; - - void DoScan(); - void ScanComplete(const AZ::Data::Asset&); - - void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - - void OnUpgradeAll(); - - // SystemTickBus::Handler - void OnSystemTick() override; - // - - // AZ::Debug::TranceMessageBus::Handler - bool OnException(const char* /*message*/) override; - bool OnPrintf(const char* /*window*/, const char* /*message*/) override; - bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - // - - bool CaptureLogFromTraceBus(const char* window, const char* message); - - enum class OperationResult - { - Success, - Failure, - }; - - void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); - - bool IsUpgrading() const; - - bool m_inProgress = false; - // scan fields - size_t m_currentAssetRowIndex = 0; - size_t m_inspectedAssets = 0; - size_t m_failedAssets = 0; - size_t m_discoveredAssets = 0; - - IUpgradeRequests::AssetList m_assetsToInspect; - IUpgradeRequests::AssetList::iterator m_inspectingAsset; - using UpgradeAssets = AZStd::vector>; - UpgradeAssets m_assetsToUpgrade; - UpgradeAssets::iterator m_inProgressAsset; - - AZ::Data::Asset m_currentAsset; - - AZStd::unique_ptr m_ui; - - AZStd::unique_ptr m_settingsCache; - - // upgrade fields - AZStd::recursive_mutex m_mutex; - bool m_upgradeComplete = false; - AZ::Data::Asset m_upgradeAsset; - int m_upgradeAssetIndex = 0; - OperationResult m_upgradeResult; - AZStd::string m_upgradeMessage; - AZStd::string m_tmpFileName; - - AZStd::unique_ptr m_keepEditorAlive; - - AZStd::deque m_logs; - - AZ::Entity* m_scriptCanvasEntity = nullptr; - - bool m_isUpgradingSingleGraph = false; - - void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); - - void FlushLogs(); - - void FinalizeUpgrade(); - void FinalizeScan(); - - void BackupComplete(); - AZStd::string BackupGraph(const AZ::Data::Asset&); - void UpgradeGraph(const AZ::Data::Asset&); - - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); - void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; - - void OnSourceFileReleased(AZ::Data::Asset asset); - - void closeEvent(QCloseEvent* event) override; - - bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); - - void Log(const char* format, ...); - }; + } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.cpp new file mode 100644 index 0000000000..710d6863f5 --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.cpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include + +namespace ModifierCpp +{ + +} + +namespace ScriptCanvasEditor +{ + namespace VersionExplorer + { + const AZStd::vector* Model::GetLogs() + { + return &m_log.GetEntries(); + } + } +} diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.h new file mode 100644 index 0000000000..44da70e85c --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Model.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once +#include +#include +#include + +namespace ScriptCanvasEditor +{ + namespace VersionExplorer + { + //! Handles model change requests, state queries; sends state change notifications + class Model + : public ModelRequestsBus::Handler + { + public: + AZ_CLASS_ALLOCATOR(Model, AZ::SystemAllocator, 0); + + const AZStd::vector* GetLogs(); + + private: + Log m_log; + + AZStd::unique_ptr m_settingsCache; + }; + } +} diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h new file mode 100644 index 0000000000..e66cdac13e --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include + +namespace ScriptCanvasEditor +{ + namespace VersionExplorer + { + class ModelRequestsTraits + : public AZ::EBusTraits + { + public: + virtual const AZStd::vector* GetLogs(); + }; + using ModelRequestsBus = AZ::EBus; + + class ModelNotificationsTraits + : public AZ::EBusTraits + { + public: + }; + 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 b96a5c6d0c..a0067e1a5f 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp @@ -6,1018 +6,17 @@ * */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -namespace VersionExplorerCpp +namespace ModifierCpp { - class FileEventHandler - : public AZ::IO::FileIOEventBus::Handler - { - public: - int m_errorCode = 0; - AZStd::string m_fileName; - FileEventHandler() - { - BusConnect(); - } - - ~FileEventHandler() - { - BusDisconnect(); - } - - void OnError(const AZ::IO::SystemFile* /*file*/, const char* fileName, int errorCode) override - { - m_errorCode = errorCode; - - if (fileName) - { - m_fileName = fileName; - } - } - }; } namespace ScriptCanvasEditor { - EditorKeepAlive::EditorKeepAlive() + namespace VersionExplorer { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) - { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); - } - } - - EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) - { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } - - Modifier::Modifier(QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent) - , m_ui(new Ui::Modifier()) - { - m_ui->setupUi(this); - - m_ui->tableWidget->horizontalHeader()->setVisible(false); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_ui->tableWidget->setColumnWidth(3, 22); - - m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - - connect(m_ui->scanButton, &QPushButton::pressed, this, &Modifier::OnScan); - connect(m_ui->closeButton, &QPushButton::pressed, this, &Modifier::OnClose); - connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &Modifier::OnUpgradeAll); - - m_ui->progressBar->setValue(0); - m_ui->progressBar->setVisible(false); - - m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); } - - Modifier::~Modifier() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } - - void Modifier::Log(const char* format, ...) - { - if (m_ui->verbose->isChecked()) - { - char sBuffer[2048]; - va_list ArgList; - va_start(ArgList, format); - azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); - sBuffer[sizeof(sBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); - } - } - - void Modifier::OnClose() - { - reject(); - } - - bool Modifier::IsUpgrading() const - { - return m_inProgressAsset != m_assetsToUpgrade.end() && m_inProgress; - } - - void Modifier::OnSystemTick() - { - switch (m_state) - { - case ProcessState::Scan: - - if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) - { - m_inProgress = true; - AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; - m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); - m_currentAsset.BlockUntilLoadComplete(); - if (m_currentAsset.IsReady()) - { - // The asset is ready, grab its info - m_inProgress = true; - InspectAsset(m_currentAsset, assetToUpgrade); - } - else - { - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem - ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - ++m_currentAssetRowIndex; - - Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_failedAssets; - ScanComplete(m_currentAsset); - } - } - break; - - case ProcessState::Upgrade: - { - AZStd::lock_guard lock(m_mutex); - if (m_upgradeComplete) - { - ++m_upgradeAssetIndex; - m_inProgress = false; - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - - if (m_scriptCanvasEntity) - { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } - - GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); - } - } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - m_settingsCache.reset(); - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } - - m_upgradeComplete = false; - } - - if (!IsUpgrading() && m_state == ProcessState::Upgrade) - { - AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); - // Make the backup - if (errorMessage.empty()) - { - Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); - QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); - spinner->SetIsBusy(true); - } - } - - // Upgrade the graph - UpgradeGraph(*m_inProgressAsset); - } - else - { - Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); - GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); - } - - } - break; - } - default: - break; - } - - FlushLogs(); - - AZ::Data::AssetManager::Instance().DispatchEvents(); - AZ::SystemTickBus::ExecuteQueuedEvents(); - } - - // Backup - - void Modifier::OnUpgradeAll() - { - m_state = ProcessState::Upgrade; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - AZ::Interface::Get()->SetIsUpgrading(true); - AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); - m_inProgressAsset = m_assetsToUpgrade.begin(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - m_keepEditorAlive = AZStd::make_unique(); - } - - AZStd::string Modifier::BackupGraph(const AZ::Data::Asset& asset) - { - if (!m_ui->makeBackupCheckbox->isChecked()) - { - // considered a success - return ""; - } - - QDateTime theTime = QDateTime::currentDateTime(); - QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); - - AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); - char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); - backupPath = backupPathCStr; - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) - { - if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); - return "Failed to create backup folder"; - } - } - - AZStd::string devRoot = "@devroot@"; - AZStd::string devAssets = "@devassets@"; - - char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); - - char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); - - AZStd::string relativePath = devAssetsCStr; - AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AZStd::string sourceFilePath; - - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); - if (sourceInfoFound) - { - AZStd::string assetPath; - AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - - sourceFilePath = assetPath; - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Modifier::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); - return "Failed to find source file"; - } - - devRoot = devRootCStr; - AzFramework::StringFunc::Path::Normalize(devRoot); - - relativePath = sourceFilePath; - AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AzFramework::StringFunc::Path::Normalize(relativePath); - AzFramework::StringFunc::Path::Normalize(backupPath); - - AZStd::string targetFilePath = backupPath; - targetFilePath += relativePath; - - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Modifier::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return "Failed to copy source file to backup location"; - } - - Log("Modifier::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return ""; - } - - void Modifier::UpgradeGraph(const AZ::Data::Asset& asset) - { - m_inProgress = true; - m_upgradeComplete = false; - Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); - m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - m_scriptCanvasEntity = nullptr; - - UpgradeNotifications::Bus::Handler::BusConnect(); - - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" - , azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "Modifier::UpgradeGraph The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return; - } - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - m_scriptCanvasEntity = scriptCanvasEntity; - - graphComponent->UpgradeGraph - ( asset - , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate - , m_ui->verbose->isChecked()); - } - } - - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - } - - void Modifier::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - if (!fullPathFound) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); - } - - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - this->OnSourceFileReleased(asset); - }); - streamer->QueueRequest(flushRequest); - } - - void Modifier::OnSourceFileReleased(AZ::Data::Asset asset) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - m_tmpFileName.clear(); - AZStd::string tmpFileName; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. - // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); - return; - } - - bool tempSavedSucceeded = false; - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - if (fileStream.IsOpen()) - { - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasEditor::ScriptCanvasAssetHandler handler; - tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); - } - - fileStream.Close(); - } - - // attempt to remove temporary file no matter what - m_tmpFileName = tmpFileName; - if (!tempSavedSucceeded) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); - return; - } - - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - constexpr const size_t k_maxAttemps = 10; - - if (!info.IsReadOnly()) - { - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - if (m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - } - } - }); - } - - void Modifier::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target - , size_t remainingAttempts) - { - VersionExplorerCpp::FileEventHandler fileEventHandler; - - if (remainingAttempts == 0) - { - // all attempts failed, give up - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); - GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); - } - else if (remainingAttempts == 2) - { - // before the final attempt, flush all caches - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); - streamer->SetRequestCompleteCallback(flushRequest - , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction( - [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - else - { - // the actual move attempt - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - m_tmpFileName.clear(); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - AZ::SystemTickBus::QueueFunction([this, asset]() - { - GraphUpgradeComplete(asset, OperationResult::Success, ""); - }); - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - } - } - - void Modifier::GraphUpgradeComplete - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - AZStd::lock_guard lock(m_mutex); - m_upgradeComplete = true; - m_upgradeResult = result; - m_upgradeMessage = message; - m_upgradeAsset = asset; - - if (!m_tmpFileName.empty()) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - - if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) - { - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); - } - } - - if (m_upgradeResult == OperationResult::Failure) - { - AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); - } - - m_tmpFileName.clear(); - } - - void Modifier::GraphUpgradeCompleteUIUpdate - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - QString text = asset.GetHint().c_str(); - QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); - - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); - - if (label->text().compare(assetName) == 0) - { - m_ui->tableWidget->removeCellWidget(row, ColumnAction); - m_ui->tableWidget->removeCellWidget(row, ColumnStatus); - - QToolButton* doneButton = new QToolButton(this); - doneButton->setToolTip("Upgrade complete"); - if (result == OperationResult::Success) - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); - } - else - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - doneButton->setToolTip(message.data()); - } - - m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); - } - } - } - } - - void Modifier::FinalizeUpgrade() - { - Log("FinalizeUpgrade!"); - m_inProgress = false; - m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(true); - m_keepEditorAlive.reset(); - m_ui->progressBar->setVisible(false); - - // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - if (assetsThatNeedManualInspection > 0) - { - m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); - } - else - { - m_ui->spinner->SetText("Upgrade complete."); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); - m_settingsCache.reset(); - } - - // Scanning - - void Modifier::OnScan() - { - m_assetsToUpgrade.clear(); - m_assetsToInspect.clear(); - m_ui->tableWidget->setRowCount(0); - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); - m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); - DoScan(); - } - - void Modifier::DoScan() - { - m_state = ProcessState::Scan; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - - AZ::SystemTickBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - - if (!m_assetsToInspect.empty()) - { - m_discoveredAssets = m_assetsToInspect.size(); - m_failedAssets = 0; - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - m_ui->progressFrame->setVisible(true); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); - m_ui->progressBar->setValue(0); - - m_ui->spinner->SetIsBusy(true); - m_ui->spinner->SetBusyIconSize(32); - - m_ui->scanButton->setEnabled(false); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(false); - - m_inspectingAsset = m_assetsToInspect.begin(); - m_keepEditorAlive = AZStd::make_unique(); - } - } - - void Modifier::BackupComplete() - { - m_currentAssetRowIndex = 0; - m_ui->progressBar->setValue(0); - DoScan(); - } - - void Modifier::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) - { - Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - if (!scriptCanvasAsset) - { - Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); - return; - } - - scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); - bool forceUpgrade = m_ui->forceUpgrade->isChecked(); - ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - - - if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) - { - ScanComplete(asset); - Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); - return; - } - - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - - if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) - { - m_assetsToUpgrade.push_back(asset); - - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); - - QPushButton* rowGoToButton = new QPushButton(this); - rowGoToButton->setText("Upgrade"); - rowGoToButton->setEnabled(false); - - connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { - - AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { - // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda - UpgradeSingle(rowGoToButton, spinner, assetInfo); - }); - - AZ::SystemTickBus::ExecuteQueuedEvents(); - - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); - } - - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; - AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); - AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); - AZ::StringFunc::Path::Normalize(path); - - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - QByteArray assetNameUtf8 = asset.GetHint().c_str(); - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - - QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { - AzQtComponents::ShowFileOnDesktop(absolutePath); - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); - ScanComplete(asset); - ++m_inspectedAssets; - ++m_currentAssetRowIndex; - } - - void Modifier::UpgradeSingle - ( QPushButton* rowGoToButton - , AzQtComponents::StyledBusyLabel* spinner - , AZ::Data::AssetInfo assetInfo) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - ( assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - - if (asset) - { - asset.BlockUntilLoadComplete(); - - if (asset.IsReady()) - { - AZ::Interface::Get()->SetIsUpgrading(true); - m_isUpgradingSingleGraph = true; - m_logs.clear(); - m_ui->textEdit->clear(); - spinner->SetIsBusy(true); - rowGoToButton->setEnabled(false); - - m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() - , [asset](const UpgradeAssets::value_type& assetToUpgrade) - { - return assetToUpgrade.GetId() == asset.GetId(); - }); - - m_state = ProcessState::Upgrade; - AZ::SystemTickBus::Handler::BusConnect(); - } - } - } - - void Modifier::ScanComplete(const AZ::Data::Asset& asset) - { - Log("ScanComplete: %s", asset.GetHint().c_str()); - m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - m_ui->scanButton->setEnabled(true); - - m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); - FlushLogs(); - - if (m_inspectingAsset == m_assetsToInspect.end()) - { - AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - } - } - - void Modifier::FinalizeScan() - { - Log("FinalizeScan()"); - - m_ui->spinner->SetIsBusy(false); - m_ui->onlyShowOutdated->setEnabled(true); - - // Enable all the Upgrade buttons - for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) - { - QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); - if (button) - { - button->setEnabled(true); - } - } - - QString spinnerText = QStringLiteral("Scan Complete"); - if (m_assetsToUpgrade.empty()) - { - spinnerText.append(" - No graphs require upgrade!"); - } - else - { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); - } - - - m_ui->spinner->SetText(spinnerText); - m_ui->progressBar->setVisible(false); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - - m_keepEditorAlive.reset(); - m_settingsCache.reset(); - m_state = ProcessState::Inactive; - } - - void Modifier::FlushLogs() - { - if (m_logs.empty()) - { - return; - } - - const QTextCursor oldCursor = m_ui->textEdit->textCursor(); - QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); - - m_ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = m_ui->textEdit->textCursor(); - - while (!m_logs.empty()) - { - auto line = "\n" + m_logs.front(); - - m_logs.pop_front(); - - textCursor.insertText(line.c_str()); - } - - scrollBar->setValue(scrollBar->maximum()); - m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); - - } - - bool Modifier::CaptureLogFromTraceBus(const char* window, const char* message) - { - if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) - { - return true; - } - - AZStd::string msg = message; - if (msg.ends_with("\n")) - { - msg = msg.substr(0, msg.size() - 1); - } - - m_logs.push_back(msg); - return m_ui->updateReportingOnly->isChecked(); - } - - bool Modifier::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Error): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool Modifier::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Warning): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool Modifier::OnException(const char* message) - { - AZStd::string msg = AZStd::string::format("(Exception): %s", message); - return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - } - - bool Modifier::OnPrintf(const char* window, const char* message) - { - return CaptureLogFromTraceBus(window, message); - } - - void Modifier::closeEvent(QCloseEvent* event) - { - m_keepEditorAlive.reset(); - - AzQtComponents::StyledDialog::closeEvent(event); - } - -#include - } 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 5f379d682a..e5a40ff096 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Modifier.h @@ -8,160 +8,16 @@ #pragma once -#if !defined(Q_MOC_RUN) -#include - -AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include - -#include #include -#include -#include -#include -#endif - -class QPushButton; - -namespace Ui -{ - class Modifier; -} - -namespace AzQtComponents -{ - class StyledBusyLabel; -} - namespace ScriptCanvasEditor { - //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog - class Modifier - : public AzQtComponents::StyledDialog - , private AZ::SystemTickBus::Handler - , private UpgradeNotifications::Bus::Handler - , private AZ::Debug::TraceMessageBus::Handler + namespace VersionExplorer { - Q_OBJECT - - public: - AZ_CLASS_ALLOCATOR(Modifier, AZ::SystemAllocator, 0); - - explicit Modifier(QWidget* parent = nullptr); - ~Modifier(); - - private: - - static constexpr int ColumnAsset = 0; - static constexpr int ColumnAction = 1; - static constexpr int ColumnBrowse = 2; - static constexpr int ColumnStatus = 3; - - void OnScan(); - void OnClose(); - - enum class ProcessState + class Modifier { - Inactive, - Backup, - Scan, - Upgrade, + public: + AZ_CLASS_ALLOCATOR(Modifier, AZ::SystemAllocator, 0); }; - ProcessState m_state = ProcessState::Inactive; - - void DoScan(); - void ScanComplete(const AZ::Data::Asset&); - - void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - - void OnUpgradeAll(); - - // SystemTickBus::Handler - void OnSystemTick() override; - // - - // AZ::Debug::TranceMessageBus::Handler - bool OnException(const char* /*message*/) override; - bool OnPrintf(const char* /*window*/, const char* /*message*/) override; - bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - // - - bool CaptureLogFromTraceBus(const char* window, const char* message); - - enum class OperationResult - { - Success, - Failure, - }; - - void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); - - bool IsUpgrading() const; - - bool m_inProgress = false; - // scan fields - size_t m_currentAssetRowIndex = 0; - size_t m_inspectedAssets = 0; - size_t m_failedAssets = 0; - size_t m_discoveredAssets = 0; - - IUpgradeRequests::AssetList m_assetsToInspect; - IUpgradeRequests::AssetList::iterator m_inspectingAsset; - using UpgradeAssets = AZStd::vector>; - UpgradeAssets m_assetsToUpgrade; - UpgradeAssets::iterator m_inProgressAsset; - - AZ::Data::Asset m_currentAsset; - - AZStd::unique_ptr m_ui; - - AZStd::unique_ptr m_settingsCache; - - // upgrade fields - AZStd::recursive_mutex m_mutex; - bool m_upgradeComplete = false; - AZ::Data::Asset m_upgradeAsset; - int m_upgradeAssetIndex = 0; - OperationResult m_upgradeResult; - AZStd::string m_upgradeMessage; - AZStd::string m_tmpFileName; - - AZStd::unique_ptr m_keepEditorAlive; - - AZStd::deque m_logs; - - AZ::Entity* m_scriptCanvasEntity = nullptr; - - bool m_isUpgradingSingleGraph = false; - - void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); - - void FlushLogs(); - - void FinalizeUpgrade(); - void FinalizeScan(); - - void BackupComplete(); - AZStd::string BackupGraph(const AZ::Data::Asset&); - void UpgradeGraph(const AZ::Data::Asset&); - - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); - void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; - - void OnSourceFileReleased(AZ::Data::Asset asset); - - void closeEvent(QCloseEvent* event) override; - - bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); - - void Log(const char* format, ...); - }; + } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp index 29f5f8f530..f74c27004b 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp @@ -6,1018 +6,17 @@ * */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -namespace VersionExplorerCpp +namespace ScannerCpp { - class FileEventHandler - : public AZ::IO::FileIOEventBus::Handler - { - public: - int m_errorCode = 0; - AZStd::string m_fileName; - FileEventHandler() - { - BusConnect(); - } - - ~FileEventHandler() - { - BusDisconnect(); - } - - void OnError(const AZ::IO::SystemFile* /*file*/, const char* fileName, int errorCode) override - { - m_errorCode = errorCode; - - if (fileName) - { - m_fileName = fileName; - } - } - }; } namespace ScriptCanvasEditor { - EditorKeepAlive::EditorKeepAlive() + namespace VersionExplorer { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) - { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); - } - } - - EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) - { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } - - Scanner::Scanner(QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent) - , m_ui(new Ui::Scanner()) - { - m_ui->setupUi(this); - - m_ui->tableWidget->horizontalHeader()->setVisible(false); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_ui->tableWidget->setColumnWidth(3, 22); - - m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - - connect(m_ui->scanButton, &QPushButton::pressed, this, &Scanner::OnScan); - connect(m_ui->closeButton, &QPushButton::pressed, this, &Scanner::OnClose); - connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &Scanner::OnUpgradeAll); - - m_ui->progressBar->setValue(0); - m_ui->progressBar->setVisible(false); - - m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); } - - Scanner::~Scanner() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } - - void Scanner::Log(const char* format, ...) - { - if (m_ui->verbose->isChecked()) - { - char sBuffer[2048]; - va_list ArgList; - va_start(ArgList, format); - azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); - sBuffer[sizeof(sBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); - } - } - - void Scanner::OnClose() - { - reject(); - } - - bool Scanner::IsUpgrading() const - { - return m_inProgressAsset != m_assetsToUpgrade.end() && m_inProgress; - } - - void Scanner::OnSystemTick() - { - switch (m_state) - { - case ProcessState::Scan: - - if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) - { - m_inProgress = true; - AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; - m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); - m_currentAsset.BlockUntilLoadComplete(); - if (m_currentAsset.IsReady()) - { - // The asset is ready, grab its info - m_inProgress = true; - InspectAsset(m_currentAsset, assetToUpgrade); - } - else - { - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem - ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - ++m_currentAssetRowIndex; - - Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_failedAssets; - ScanComplete(m_currentAsset); - } - } - break; - - case ProcessState::Upgrade: - { - AZStd::lock_guard lock(m_mutex); - if (m_upgradeComplete) - { - ++m_upgradeAssetIndex; - m_inProgress = false; - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - - if (m_scriptCanvasEntity) - { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } - - GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); - } - } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - m_settingsCache.reset(); - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } - - m_upgradeComplete = false; - } - - if (!IsUpgrading() && m_state == ProcessState::Upgrade) - { - AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); - // Make the backup - if (errorMessage.empty()) - { - Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); - QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); - spinner->SetIsBusy(true); - } - } - - // Upgrade the graph - UpgradeGraph(*m_inProgressAsset); - } - else - { - Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); - GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); - } - - } - break; - } - default: - break; - } - - FlushLogs(); - - AZ::Data::AssetManager::Instance().DispatchEvents(); - AZ::SystemTickBus::ExecuteQueuedEvents(); - } - - // Backup - - void Scanner::OnUpgradeAll() - { - m_state = ProcessState::Upgrade; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - AZ::Interface::Get()->SetIsUpgrading(true); - AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); - m_inProgressAsset = m_assetsToUpgrade.begin(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - m_keepEditorAlive = AZStd::make_unique(); - } - - AZStd::string Scanner::BackupGraph(const AZ::Data::Asset& asset) - { - if (!m_ui->makeBackupCheckbox->isChecked()) - { - // considered a success - return ""; - } - - QDateTime theTime = QDateTime::currentDateTime(); - QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); - - AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); - char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); - backupPath = backupPathCStr; - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) - { - if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); - return "Failed to create backup folder"; - } - } - - AZStd::string devRoot = "@devroot@"; - AZStd::string devAssets = "@devassets@"; - - char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); - - char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); - - AZStd::string relativePath = devAssetsCStr; - AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AZStd::string sourceFilePath; - - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); - if (sourceInfoFound) - { - AZStd::string assetPath; - AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - - sourceFilePath = assetPath; - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Scanner::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); - return "Failed to find source file"; - } - - devRoot = devRootCStr; - AzFramework::StringFunc::Path::Normalize(devRoot); - - relativePath = sourceFilePath; - AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AzFramework::StringFunc::Path::Normalize(relativePath); - AzFramework::StringFunc::Path::Normalize(backupPath); - - AZStd::string targetFilePath = backupPath; - targetFilePath += relativePath; - - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Scanner::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return "Failed to copy source file to backup location"; - } - - Log("Scanner::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return ""; - } - - void Scanner::UpgradeGraph(const AZ::Data::Asset& asset) - { - m_inProgress = true; - m_upgradeComplete = false; - Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); - m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - m_scriptCanvasEntity = nullptr; - - UpgradeNotifications::Bus::Handler::BusConnect(); - - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" - , azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "Scanner::UpgradeGraph The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return; - } - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - m_scriptCanvasEntity = scriptCanvasEntity; - - graphComponent->UpgradeGraph - ( asset - , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate - , m_ui->verbose->isChecked()); - } - } - - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - } - - void Scanner::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - if (!fullPathFound) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); - } - - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - this->OnSourceFileReleased(asset); - }); - streamer->QueueRequest(flushRequest); - } - - void Scanner::OnSourceFileReleased(AZ::Data::Asset asset) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - m_tmpFileName.clear(); - AZStd::string tmpFileName; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. - // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); - return; - } - - bool tempSavedSucceeded = false; - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - if (fileStream.IsOpen()) - { - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasEditor::ScriptCanvasAssetHandler handler; - tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); - } - - fileStream.Close(); - } - - // attempt to remove temporary file no matter what - m_tmpFileName = tmpFileName; - if (!tempSavedSucceeded) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); - return; - } - - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - constexpr const size_t k_maxAttemps = 10; - - if (!info.IsReadOnly()) - { - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - if (m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - } - } - }); - } - - void Scanner::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target - , size_t remainingAttempts) - { - VersionExplorerCpp::FileEventHandler fileEventHandler; - - if (remainingAttempts == 0) - { - // all attempts failed, give up - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); - GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); - } - else if (remainingAttempts == 2) - { - // before the final attempt, flush all caches - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); - streamer->SetRequestCompleteCallback(flushRequest - , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction( - [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - else - { - // the actual move attempt - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - m_tmpFileName.clear(); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - AZ::SystemTickBus::QueueFunction([this, asset]() - { - GraphUpgradeComplete(asset, OperationResult::Success, ""); - }); - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - } - } - - void Scanner::GraphUpgradeComplete - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - AZStd::lock_guard lock(m_mutex); - m_upgradeComplete = true; - m_upgradeResult = result; - m_upgradeMessage = message; - m_upgradeAsset = asset; - - if (!m_tmpFileName.empty()) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - - if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) - { - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); - } - } - - if (m_upgradeResult == OperationResult::Failure) - { - AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); - } - - m_tmpFileName.clear(); - } - - void Scanner::GraphUpgradeCompleteUIUpdate - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - QString text = asset.GetHint().c_str(); - QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); - - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); - - if (label->text().compare(assetName) == 0) - { - m_ui->tableWidget->removeCellWidget(row, ColumnAction); - m_ui->tableWidget->removeCellWidget(row, ColumnStatus); - - QToolButton* doneButton = new QToolButton(this); - doneButton->setToolTip("Upgrade complete"); - if (result == OperationResult::Success) - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); - } - else - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - doneButton->setToolTip(message.data()); - } - - m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); - } - } - } - } - - void Scanner::FinalizeUpgrade() - { - Log("FinalizeUpgrade!"); - m_inProgress = false; - m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(true); - m_keepEditorAlive.reset(); - m_ui->progressBar->setVisible(false); - - // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - if (assetsThatNeedManualInspection > 0) - { - m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); - } - else - { - m_ui->spinner->SetText("Upgrade complete."); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); - m_settingsCache.reset(); - } - - // Scanning - - void Scanner::OnScan() - { - m_assetsToUpgrade.clear(); - m_assetsToInspect.clear(); - m_ui->tableWidget->setRowCount(0); - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); - m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); - DoScan(); - } - - void Scanner::DoScan() - { - m_state = ProcessState::Scan; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - - AZ::SystemTickBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - - if (!m_assetsToInspect.empty()) - { - m_discoveredAssets = m_assetsToInspect.size(); - m_failedAssets = 0; - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - m_ui->progressFrame->setVisible(true); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); - m_ui->progressBar->setValue(0); - - m_ui->spinner->SetIsBusy(true); - m_ui->spinner->SetBusyIconSize(32); - - m_ui->scanButton->setEnabled(false); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(false); - - m_inspectingAsset = m_assetsToInspect.begin(); - m_keepEditorAlive = AZStd::make_unique(); - } - } - - void Scanner::BackupComplete() - { - m_currentAssetRowIndex = 0; - m_ui->progressBar->setValue(0); - DoScan(); - } - - void Scanner::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) - { - Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - if (!scriptCanvasAsset) - { - Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); - return; - } - - scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); - bool forceUpgrade = m_ui->forceUpgrade->isChecked(); - ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - - - if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) - { - ScanComplete(asset); - Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); - return; - } - - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - - if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) - { - m_assetsToUpgrade.push_back(asset); - - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); - - QPushButton* rowGoToButton = new QPushButton(this); - rowGoToButton->setText("Upgrade"); - rowGoToButton->setEnabled(false); - - connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { - - AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { - // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda - UpgradeSingle(rowGoToButton, spinner, assetInfo); - }); - - AZ::SystemTickBus::ExecuteQueuedEvents(); - - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); - } - - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; - AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); - AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); - AZ::StringFunc::Path::Normalize(path); - - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - QByteArray assetNameUtf8 = asset.GetHint().c_str(); - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - - QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { - AzQtComponents::ShowFileOnDesktop(absolutePath); - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); - ScanComplete(asset); - ++m_inspectedAssets; - ++m_currentAssetRowIndex; - } - - void Scanner::UpgradeSingle - ( QPushButton* rowGoToButton - , AzQtComponents::StyledBusyLabel* spinner - , AZ::Data::AssetInfo assetInfo) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - ( assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - - if (asset) - { - asset.BlockUntilLoadComplete(); - - if (asset.IsReady()) - { - AZ::Interface::Get()->SetIsUpgrading(true); - m_isUpgradingSingleGraph = true; - m_logs.clear(); - m_ui->textEdit->clear(); - spinner->SetIsBusy(true); - rowGoToButton->setEnabled(false); - - m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() - , [asset](const UpgradeAssets::value_type& assetToUpgrade) - { - return assetToUpgrade.GetId() == asset.GetId(); - }); - - m_state = ProcessState::Upgrade; - AZ::SystemTickBus::Handler::BusConnect(); - } - } - } - - void Scanner::ScanComplete(const AZ::Data::Asset& asset) - { - Log("ScanComplete: %s", asset.GetHint().c_str()); - m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - m_ui->scanButton->setEnabled(true); - - m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); - FlushLogs(); - - if (m_inspectingAsset == m_assetsToInspect.end()) - { - AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - } - } - - void Scanner::FinalizeScan() - { - Log("FinalizeScan()"); - - m_ui->spinner->SetIsBusy(false); - m_ui->onlyShowOutdated->setEnabled(true); - - // Enable all the Upgrade buttons - for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) - { - QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); - if (button) - { - button->setEnabled(true); - } - } - - QString spinnerText = QStringLiteral("Scan Complete"); - if (m_assetsToUpgrade.empty()) - { - spinnerText.append(" - No graphs require upgrade!"); - } - else - { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); - } - - - m_ui->spinner->SetText(spinnerText); - m_ui->progressBar->setVisible(false); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - - m_keepEditorAlive.reset(); - m_settingsCache.reset(); - m_state = ProcessState::Inactive; - } - - void Scanner::FlushLogs() - { - if (m_logs.empty()) - { - return; - } - - const QTextCursor oldCursor = m_ui->textEdit->textCursor(); - QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); - - m_ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = m_ui->textEdit->textCursor(); - - while (!m_logs.empty()) - { - auto line = "\n" + m_logs.front(); - - m_logs.pop_front(); - - textCursor.insertText(line.c_str()); - } - - scrollBar->setValue(scrollBar->maximum()); - m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); - - } - - bool Scanner::CaptureLogFromTraceBus(const char* window, const char* message) - { - if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) - { - return true; - } - - AZStd::string msg = message; - if (msg.ends_with("\n")) - { - msg = msg.substr(0, msg.size() - 1); - } - - m_logs.push_back(msg); - return m_ui->updateReportingOnly->isChecked(); - } - - bool Scanner::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Error): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool Scanner::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Warning): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool Scanner::OnException(const char* message) - { - AZStd::string msg = AZStd::string::format("(Exception): %s", message); - return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - } - - bool Scanner::OnPrintf(const char* window, const char* message) - { - return CaptureLogFromTraceBus(window, message); - } - - void Scanner::closeEvent(QCloseEvent* event) - { - m_keepEditorAlive.reset(); - - AzQtComponents::StyledDialog::closeEvent(event); - } - -#include - } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.h index 574b2b2503..19642a07f1 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/Scanner.h @@ -8,160 +8,16 @@ #pragma once -#if !defined(Q_MOC_RUN) -#include - -AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include - -#include #include -#include -#include -#include -#endif - -class QPushButton; - -namespace Ui -{ - class Scanner; -} - -namespace AzQtComponents -{ - class StyledBusyLabel; -} - namespace ScriptCanvasEditor { - //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog - class Scanner - : public AzQtComponents::StyledDialog - , private AZ::SystemTickBus::Handler - , private UpgradeNotifications::Bus::Handler - , private AZ::Debug::TraceMessageBus::Handler + namespace VersionExplorer { - Q_OBJECT - - public: - AZ_CLASS_ALLOCATOR(Scanner, AZ::SystemAllocator, 0); - - explicit Scanner(QWidget* parent = nullptr); - ~Scanner(); - - private: - - static constexpr int ColumnAsset = 0; - static constexpr int ColumnAction = 1; - static constexpr int ColumnBrowse = 2; - static constexpr int ColumnStatus = 3; - - void OnScan(); - void OnClose(); - - enum class ProcessState + class Scanner { - Inactive, - Backup, - Scan, - Upgrade, + public: + AZ_CLASS_ALLOCATOR(Scanner, AZ::SystemAllocator, 0); }; - ProcessState m_state = ProcessState::Inactive; - - void DoScan(); - void ScanComplete(const AZ::Data::Asset&); - - void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - - void OnUpgradeAll(); - - // SystemTickBus::Handler - void OnSystemTick() override; - // - - // AZ::Debug::TranceMessageBus::Handler - bool OnException(const char* /*message*/) override; - bool OnPrintf(const char* /*window*/, const char* /*message*/) override; - bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - // - - bool CaptureLogFromTraceBus(const char* window, const char* message); - - enum class OperationResult - { - Success, - Failure, - }; - - void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); - - bool IsUpgrading() const; - - bool m_inProgress = false; - // scan fields - size_t m_currentAssetRowIndex = 0; - size_t m_inspectedAssets = 0; - size_t m_failedAssets = 0; - size_t m_discoveredAssets = 0; - - IUpgradeRequests::AssetList m_assetsToInspect; - IUpgradeRequests::AssetList::iterator m_inspectingAsset; - using UpgradeAssets = AZStd::vector>; - UpgradeAssets m_assetsToUpgrade; - UpgradeAssets::iterator m_inProgressAsset; - - AZ::Data::Asset m_currentAsset; - - AZStd::unique_ptr m_ui; - - AZStd::unique_ptr m_settingsCache; - - // upgrade fields - AZStd::recursive_mutex m_mutex; - bool m_upgradeComplete = false; - AZ::Data::Asset m_upgradeAsset; - int m_upgradeAssetIndex = 0; - OperationResult m_upgradeResult; - AZStd::string m_upgradeMessage; - AZStd::string m_tmpFileName; - - AZStd::unique_ptr m_keepEditorAlive; - - AZStd::deque m_logs; - - AZ::Entity* m_scriptCanvasEntity = nullptr; - - bool m_isUpgradingSingleGraph = false; - - void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); - - void FlushLogs(); - - void FinalizeUpgrade(); - void FinalizeScan(); - - void BackupComplete(); - AZStd::string BackupGraph(const AZ::Data::Asset&); - void UpgradeGraph(const AZ::Data::Asset&); - - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); - void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; - - void OnSourceFileReleased(AZ::Data::Asset asset); - - void closeEvent(QCloseEvent* event) override; - - bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); - - void Log(const char* format, ...); - }; + } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.cpp index 6c9acea25c..be4b619bfd 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.cpp @@ -6,1018 +6,94 @@ * */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -namespace VersionExplorerCpp +namespace LoggerCpp { - class FileEventHandler - : public AZ::IO::FileIOEventBus::Handler - { - public: - int m_errorCode = 0; - AZStd::string m_fileName; - FileEventHandler() - { - BusConnect(); - } - - ~FileEventHandler() - { - BusDisconnect(); - } - - void OnError(const AZ::IO::SystemFile* /*file*/, const char* fileName, int errorCode) override - { - m_errorCode = errorCode; - - if (fileName) - { - m_fileName = fileName; - } - } - }; } namespace ScriptCanvasEditor { - EditorKeepAlive::EditorKeepAlive() + namespace VersionExplorer { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) + void Log::Activate() { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); + AZ::Debug::TraceMessageBus::Handler::BusConnect(); } - } - EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) + void Log::AddEntry(const char* format, ...) { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } - - VersionExplorerLog::VersionExplorerLog(QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent) - , m_ui(new Ui::VersionExplorerLog()) - { - m_ui->setupUi(this); - - m_ui->tableWidget->horizontalHeader()->setVisible(false); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_ui->tableWidget->setColumnWidth(3, 22); - - m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - - connect(m_ui->scanButton, &QPushButton::pressed, this, &VersionExplorerLog::OnScan); - connect(m_ui->closeButton, &QPushButton::pressed, this, &VersionExplorerLog::OnClose); - connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &VersionExplorerLog::OnUpgradeAll); - - m_ui->progressBar->setValue(0); - m_ui->progressBar->setVisible(false); - - m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); - - } - - VersionExplorerLog::~VersionExplorerLog() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } - - void VersionExplorerLog::Log(const char* format, ...) - { - if (m_ui->verbose->isChecked()) - { - char sBuffer[2048]; - va_list ArgList; - va_start(ArgList, format); - azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); - sBuffer[sizeof(sBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); - } - } - - void VersionExplorerLog::OnClose() - { - reject(); - } - - bool VersionExplorerLog::IsUpgrading() const - { - return m_inProgressAsset != m_assetsToUpgrade.end() && m_inProgress; - } - - void VersionExplorerLog::OnSystemTick() - { - switch (m_state) - { - case ProcessState::Scan: - - if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) + if (m_isVerbose) { - m_inProgress = true; - AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; - m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); - m_currentAsset.BlockUntilLoadComplete(); - if (m_currentAsset.IsReady()) - { - // The asset is ready, grab its info - m_inProgress = true; - InspectAsset(m_currentAsset, assetToUpgrade); - } - else - { - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem - ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - ++m_currentAssetRowIndex; - - Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_failedAssets; - ScanComplete(m_currentAsset); - } - } - break; - - case ProcessState::Upgrade: - { - AZStd::lock_guard lock(m_mutex); - if (m_upgradeComplete) - { - ++m_upgradeAssetIndex; - m_inProgress = false; - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - - if (m_scriptCanvasEntity) - { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } - - GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); - } - } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - m_settingsCache.reset(); - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } - - m_upgradeComplete = false; - } - - if (!IsUpgrading() && m_state == ProcessState::Upgrade) - { - AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); - // Make the backup - if (errorMessage.empty()) - { - Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); - QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); - spinner->SetIsBusy(true); - } - } - - // Upgrade the graph - UpgradeGraph(*m_inProgressAsset); - } - else - { - Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); - GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); - } - - } - break; - } - default: - break; - } - - FlushLogs(); - - AZ::Data::AssetManager::Instance().DispatchEvents(); - AZ::SystemTickBus::ExecuteQueuedEvents(); - } - - // Backup - - void VersionExplorerLog::OnUpgradeAll() - { - m_state = ProcessState::Upgrade; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - AZ::Interface::Get()->SetIsUpgrading(true); - AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); - m_inProgressAsset = m_assetsToUpgrade.begin(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - m_keepEditorAlive = AZStd::make_unique(); - } - - AZStd::string VersionExplorerLog::BackupGraph(const AZ::Data::Asset& asset) - { - if (!m_ui->makeBackupCheckbox->isChecked()) - { - // considered a success - return ""; - } - - QDateTime theTime = QDateTime::currentDateTime(); - QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); - - AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); - char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); - backupPath = backupPathCStr; - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) - { - if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); - return "Failed to create backup folder"; + char sBuffer[2048]; + va_list ArgList; + va_start(ArgList, format); + azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); + sBuffer[sizeof(sBuffer) - 1] = '\0'; + va_end(ArgList); + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); } } - AZStd::string devRoot = "@devroot@"; - AZStd::string devAssets = "@devassets@"; - - char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); - - char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); - - AZStd::string relativePath = devAssetsCStr; - AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); - if (relativePath.starts_with("/")) + bool Log::CaptureFromTraceBus(const char* window, const char* message) { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AZStd::string sourceFilePath; - - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); - if (sourceInfoFound) - { - AZStd::string assetPath; - AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - - sourceFilePath = assetPath; - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorerLog::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); - return "Failed to find source file"; - } - - devRoot = devRootCStr; - AzFramework::StringFunc::Path::Normalize(devRoot); - - relativePath = sourceFilePath; - AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AzFramework::StringFunc::Path::Normalize(relativePath); - AzFramework::StringFunc::Path::Normalize(backupPath); - - AZStd::string targetFilePath = backupPath; - targetFilePath += relativePath; - - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorerLog::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return "Failed to copy source file to backup location"; - } - - Log("VersionExplorerLog::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return ""; - } - - void VersionExplorerLog::UpgradeGraph(const AZ::Data::Asset& asset) - { - m_inProgress = true; - m_upgradeComplete = false; - Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); - m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - m_scriptCanvasEntity = nullptr; - - UpgradeNotifications::Bus::Handler::BusConnect(); - - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" - , azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) + if (m_isExclusiveReportingEnabled && window != ScriptCanvas::k_VersionExplorerWindow) { - return; + return true; } - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "VersionExplorerLog::UpgradeGraph The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) + AZStd::string msg = message; + if (msg.ends_with("\n")) { - return; + msg = msg.substr(0, msg.size() - 1); } - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - m_scriptCanvasEntity = scriptCanvasEntity; - - graphComponent->UpgradeGraph - ( asset - , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate - , m_ui->verbose->isChecked()); - } + m_logs.push_back(msg); + return m_isExclusiveReportingEnabled; } - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - } - - void VersionExplorerLog::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - if (!fullPathFound) + void Log::Deactivate() { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); + AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); } - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) + const AZStd::vector& Log::GetEntries() const { - this->OnSourceFileReleased(asset); - }); - streamer->QueueRequest(flushRequest); - } - - void VersionExplorerLog::OnSourceFileReleased(AZ::Data::Asset asset) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - m_tmpFileName.clear(); - AZStd::string tmpFileName; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. - // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); - return; + return m_logs; } - bool tempSavedSucceeded = false; - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - if (fileStream.IsOpen()) + void Log::SetVersionExporerExclusivity(bool enabled) { - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasEditor::ScriptCanvasAssetHandler handler; - tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); - } - - fileStream.Close(); + m_isExclusiveReportingEnabled = enabled; } - // attempt to remove temporary file no matter what - m_tmpFileName = tmpFileName; - if (!tempSavedSucceeded) + void Log::SetVerbose(bool verbosity) { - GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); - return; + m_isVerbose = verbosity; } - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) + bool Log::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) { - constexpr const size_t k_maxAttemps = 10; - - if (!info.IsReadOnly()) - { - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - if (m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - else - { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) - { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); - } - } - } - }); - } - - void VersionExplorerLog::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target - , size_t remainingAttempts) - { - VersionExplorerCpp::FileEventHandler fileEventHandler; - - if (remainingAttempts == 0) - { - // all attempts failed, give up - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); - GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); - } - else if (remainingAttempts == 2) - { - // before the final attempt, flush all caches - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); - streamer->SetRequestCompleteCallback(flushRequest - , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction( - [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - else - { - // the actual move attempt - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - m_tmpFileName.clear(); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - AZ::SystemTickBus::QueueFunction([this, asset]() - { - GraphUpgradeComplete(asset, OperationResult::Success, ""); - }); - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - } - } - - void VersionExplorerLog::GraphUpgradeComplete - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - AZStd::lock_guard lock(m_mutex); - m_upgradeComplete = true; - m_upgradeResult = result; - m_upgradeMessage = message; - m_upgradeAsset = asset; - - if (!m_tmpFileName.empty()) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - - if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) - { - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); - } + AZStd::string msg = AZStd::string::format("(Error): %s", message); + return CaptureFromTraceBus(window, msg.c_str()); } - if (m_upgradeResult == OperationResult::Failure) + bool Log::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) { - AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); + AZStd::string msg = AZStd::string::format("(Warning): %s", message); + return CaptureFromTraceBus(window, msg.c_str()); } - m_tmpFileName.clear(); - } - - void VersionExplorerLog::GraphUpgradeCompleteUIUpdate - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - QString text = asset.GetHint().c_str(); - QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); - - if (!items.isEmpty()) + bool Log::OnException(const char* message) { - for (auto* item : items) - { - int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); + AZStd::string msg = AZStd::string::format("(Exception): %s", message); + return CaptureFromTraceBus("Script Canvas", msg.c_str()); + } - if (label->text().compare(assetName) == 0) - { - m_ui->tableWidget->removeCellWidget(row, ColumnAction); - m_ui->tableWidget->removeCellWidget(row, ColumnStatus); - - QToolButton* doneButton = new QToolButton(this); - doneButton->setToolTip("Upgrade complete"); - if (result == OperationResult::Success) - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); - } - else - { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - doneButton->setToolTip(message.data()); - } - - m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); - } - } + bool Log::OnPrintf(const char* window, const char* message) + { + return CaptureFromTraceBus(window, message); } } - - void VersionExplorerLog::FinalizeUpgrade() - { - Log("FinalizeUpgrade!"); - m_inProgress = false; - m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(true); - m_keepEditorAlive.reset(); - m_ui->progressBar->setVisible(false); - - // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - if (assetsThatNeedManualInspection > 0) - { - m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); - } - else - { - m_ui->spinner->SetText("Upgrade complete."); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); - m_settingsCache.reset(); - } - - // Scanning - - void VersionExplorerLog::OnScan() - { - m_assetsToUpgrade.clear(); - m_assetsToInspect.clear(); - m_ui->tableWidget->setRowCount(0); - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); - m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); - DoScan(); - } - - void VersionExplorerLog::DoScan() - { - m_state = ProcessState::Scan; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - - AZ::SystemTickBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - - if (!m_assetsToInspect.empty()) - { - m_discoveredAssets = m_assetsToInspect.size(); - m_failedAssets = 0; - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - m_ui->progressFrame->setVisible(true); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); - m_ui->progressBar->setValue(0); - - m_ui->spinner->SetIsBusy(true); - m_ui->spinner->SetBusyIconSize(32); - - m_ui->scanButton->setEnabled(false); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(false); - - m_inspectingAsset = m_assetsToInspect.begin(); - m_keepEditorAlive = AZStd::make_unique(); - } - } - - void VersionExplorerLog::BackupComplete() - { - m_currentAssetRowIndex = 0; - m_ui->progressBar->setValue(0); - DoScan(); - } - - void VersionExplorerLog::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) - { - Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - if (!scriptCanvasAsset) - { - Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); - return; - } - - scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - } - - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); - bool forceUpgrade = m_ui->forceUpgrade->isChecked(); - ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - - - if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) - { - ScanComplete(asset); - Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); - return; - } - - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - - if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) - { - m_assetsToUpgrade.push_back(asset); - - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); - - QPushButton* rowGoToButton = new QPushButton(this); - rowGoToButton->setText("Upgrade"); - rowGoToButton->setEnabled(false); - - connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { - - AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { - // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda - UpgradeSingle(rowGoToButton, spinner, assetInfo); - }); - - AZ::SystemTickBus::ExecuteQueuedEvents(); - - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); - } - - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; - AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); - AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); - AZ::StringFunc::Path::Normalize(path); - - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - QByteArray assetNameUtf8 = asset.GetHint().c_str(); - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - - QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { - AzQtComponents::ShowFileOnDesktop(absolutePath); - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); - ScanComplete(asset); - ++m_inspectedAssets; - ++m_currentAssetRowIndex; - } - - void VersionExplorerLog::UpgradeSingle - ( QPushButton* rowGoToButton - , AzQtComponents::StyledBusyLabel* spinner - , AZ::Data::AssetInfo assetInfo) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - ( assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - - if (asset) - { - asset.BlockUntilLoadComplete(); - - if (asset.IsReady()) - { - AZ::Interface::Get()->SetIsUpgrading(true); - m_isUpgradingSingleGraph = true; - m_logs.clear(); - m_ui->textEdit->clear(); - spinner->SetIsBusy(true); - rowGoToButton->setEnabled(false); - - m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() - , [asset](const UpgradeAssets::value_type& assetToUpgrade) - { - return assetToUpgrade.GetId() == asset.GetId(); - }); - - m_state = ProcessState::Upgrade; - AZ::SystemTickBus::Handler::BusConnect(); - } - } - } - - void VersionExplorerLog::ScanComplete(const AZ::Data::Asset& asset) - { - Log("ScanComplete: %s", asset.GetHint().c_str()); - m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - m_ui->scanButton->setEnabled(true); - - m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); - FlushLogs(); - - if (m_inspectingAsset == m_assetsToInspect.end()) - { - AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - } - } - - void VersionExplorerLog::FinalizeScan() - { - Log("FinalizeScan()"); - - m_ui->spinner->SetIsBusy(false); - m_ui->onlyShowOutdated->setEnabled(true); - - // Enable all the Upgrade buttons - for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) - { - QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); - if (button) - { - button->setEnabled(true); - } - } - - QString spinnerText = QStringLiteral("Scan Complete"); - if (m_assetsToUpgrade.empty()) - { - spinnerText.append(" - No graphs require upgrade!"); - } - else - { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); - } - - - m_ui->spinner->SetText(spinnerText); - m_ui->progressBar->setVisible(false); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - - m_keepEditorAlive.reset(); - m_settingsCache.reset(); - m_state = ProcessState::Inactive; - } - - void VersionExplorerLog::FlushLogs() - { - if (m_logs.empty()) - { - return; - } - - const QTextCursor oldCursor = m_ui->textEdit->textCursor(); - QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); - - m_ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = m_ui->textEdit->textCursor(); - - while (!m_logs.empty()) - { - auto line = "\n" + m_logs.front(); - - m_logs.pop_front(); - - textCursor.insertText(line.c_str()); - } - - scrollBar->setValue(scrollBar->maximum()); - m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); - - } - - bool VersionExplorerLog::CaptureLogFromTraceBus(const char* window, const char* message) - { - if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) - { - return true; - } - - AZStd::string msg = message; - if (msg.ends_with("\n")) - { - msg = msg.substr(0, msg.size() - 1); - } - - m_logs.push_back(msg); - return m_ui->updateReportingOnly->isChecked(); - } - - bool VersionExplorerLog::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Error): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorerLog::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Warning): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorerLog::OnException(const char* message) - { - AZStd::string msg = AZStd::string::format("(Exception): %s", message); - return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - } - - bool VersionExplorerLog::OnPrintf(const char* window, const char* message) - { - return CaptureLogFromTraceBus(window, message); - } - - void VersionExplorerLog::closeEvent(QCloseEvent* event) - { - m_keepEditorAlive.reset(); - - AzQtComponents::StyledDialog::closeEvent(event); - } - -#include - } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h index 498b2f7745..1ba8e8c9b1 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h @@ -8,160 +8,36 @@ #pragma once -#if !defined(Q_MOC_RUN) -#include - -AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") -#include -AZ_POP_DISABLE_WARNING - -#include -#include -#include - -#include #include - -#include -#include #include -#endif - -class QPushButton; - -namespace Ui -{ - class VersionExplorerLog; -} - -namespace AzQtComponents -{ - class StyledBusyLabel; -} namespace ScriptCanvasEditor { - //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog - class VersionExplorerLog - : public AzQtComponents::StyledDialog - , private AZ::SystemTickBus::Handler - , private UpgradeNotifications::Bus::Handler - , private AZ::Debug::TraceMessageBus::Handler + namespace VersionExplorer { - Q_OBJECT - - public: - AZ_CLASS_ALLOCATOR(VersionExplorerLog, AZ::SystemAllocator, 0); - - explicit VersionExplorerLog(QWidget* parent = nullptr); - ~VersionExplorerLog(); - - private: - - static constexpr int ColumnAsset = 0; - static constexpr int ColumnAction = 1; - static constexpr int ColumnBrowse = 2; - static constexpr int ColumnStatus = 3; - - void OnScan(); - void OnClose(); - - enum class ProcessState + class Log + : private AZ::Debug::TraceMessageBus::Handler { - Inactive, - Backup, - Scan, - Upgrade, + public: + AZ_CLASS_ALLOCATOR(Log, AZ::SystemAllocator, 0); + + void Activate(); + void AddEntry(const char* format, ...); + void Deactivate(); + const AZStd::vector& GetEntries() const; + void SetVersionExporerExclusivity(bool enabled); + void SetVerbose(bool verbosity); + + private: + bool m_isExclusiveReportingEnabled = false; + bool m_isVerbose = false; + AZStd::vector m_logs; + + bool CaptureFromTraceBus(const char* window, const char* message); + bool OnException(const char* /*message*/) override; + bool OnPrintf(const char* /*window*/, const char* /*message*/) override; + bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; + bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; }; - ProcessState m_state = ProcessState::Inactive; - - void DoScan(); - void ScanComplete(const AZ::Data::Asset&); - - void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - - void OnUpgradeAll(); - - // SystemTickBus::Handler - void OnSystemTick() override; - // - - // AZ::Debug::TranceMessageBus::Handler - bool OnException(const char* /*message*/) override; - bool OnPrintf(const char* /*window*/, const char* /*message*/) override; - bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - // - - bool CaptureLogFromTraceBus(const char* window, const char* message); - - enum class OperationResult - { - Success, - Failure, - }; - - void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); - - bool IsUpgrading() const; - - bool m_inProgress = false; - // scan fields - size_t m_currentAssetRowIndex = 0; - size_t m_inspectedAssets = 0; - size_t m_failedAssets = 0; - size_t m_discoveredAssets = 0; - - IUpgradeRequests::AssetList m_assetsToInspect; - IUpgradeRequests::AssetList::iterator m_inspectingAsset; - using UpgradeAssets = AZStd::vector>; - UpgradeAssets m_assetsToUpgrade; - UpgradeAssets::iterator m_inProgressAsset; - - AZ::Data::Asset m_currentAsset; - - AZStd::unique_ptr m_ui; - - AZStd::unique_ptr m_settingsCache; - - // upgrade fields - AZStd::recursive_mutex m_mutex; - bool m_upgradeComplete = false; - AZ::Data::Asset m_upgradeAsset; - int m_upgradeAssetIndex = 0; - OperationResult m_upgradeResult; - AZStd::string m_upgradeMessage; - AZStd::string m_tmpFileName; - - AZStd::unique_ptr m_keepEditorAlive; - - AZStd::deque m_logs; - - AZ::Entity* m_scriptCanvasEntity = nullptr; - - bool m_isUpgradingSingleGraph = false; - - void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); - - void FlushLogs(); - - void FinalizeUpgrade(); - void FinalizeScan(); - - void BackupComplete(); - AZStd::string BackupGraph(const AZ::Data::Asset&); - void UpgradeGraph(const AZ::Data::Asset&); - - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); - void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; - - void OnSourceFileReleased(AZ::Data::Asset asset); - - void closeEvent(QCloseEvent* event) override; - - bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); - - void Log(const char* format, ...); - }; + } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerTraits.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerTraits.h deleted file mode 100644 index 2b23c711dd..0000000000 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/VersionExplorerTraits.h +++ /dev/null @@ -1,22 +0,0 @@ -#include - -namespace ScriptCanvasEditor -{ - namespace VersionExplorer - { - class RequestsTraits : public AZ::EBusTraits - { - public: - static const AZ::EBusAddressPolicy HandlerPolicy = AZ::EBusAddressPolicy::Single; - }; - using RequestsBus = AZ::EBus; - - class NotificationsTraits : public AZ::EBusTraits - { - public: - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - using BusIdType = NotificationsTraits*; - }; - using NotificationsBus = AZ::EBus; - } -} diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.cpp b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.cpp index eb182ed291..bf407765e1 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.cpp +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.cpp @@ -28,996 +28,909 @@ #include #include #include -#include -#include +#include +#include #include #include #include -namespace VersionExplorerCpp -{ - class FileEventHandler - : public AZ::IO::FileIOEventBus::Handler - { - public: - int m_errorCode = 0; - AZStd::string m_fileName; - - FileEventHandler() - { - BusConnect(); - } - - ~FileEventHandler() - { - BusDisconnect(); - } - - void OnError(const AZ::IO::SystemFile* /*file*/, const char* fileName, int errorCode) override - { - m_errorCode = errorCode; - - if (fileName) - { - m_fileName = fileName; - } - } - }; -} - namespace ScriptCanvasEditor { - EditorKeepAlive::EditorKeepAlive() + namespace VersionExplorer { - ISystem* system = nullptr; - CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - - m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - - if (m_edKeepEditorActive) + EditorKeepAlive::EditorKeepAlive() { - m_keepEditorActive = m_edKeepEditorActive->GetIVal(); - m_edKeepEditorActive->Set(1); - } - } + ISystem* system = nullptr; + CrySystemRequestBus::BroadcastResult(system, &CrySystemRequestBus::Events::GetCrySystem); - EditorKeepAlive::~EditorKeepAlive() - { - if (m_edKeepEditorActive) - { - m_edKeepEditorActive->Set(m_keepEditorActive); - } - } + m_edKeepEditorActive = system->GetIConsole()->GetCVar("ed_KeepEditorActive"); - VersionExplorer::VersionExplorer(QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent) - , m_ui(new Ui::VersionExplorer()) - { - m_ui->setupUi(this); - - m_ui->tableWidget->horizontalHeader()->setVisible(false); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); - m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); - m_ui->tableWidget->setColumnWidth(3, 22); - - m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); - m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); - - connect(m_ui->scanButton, &QPushButton::pressed, this, &VersionExplorer::OnScan); - connect(m_ui->closeButton, &QPushButton::pressed, this, &VersionExplorer::OnClose); - connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &VersionExplorer::OnUpgradeAll); - - m_ui->progressBar->setValue(0); - m_ui->progressBar->setVisible(false); - - m_keepEditorAlive = AZStd::make_unique(); - m_inspectingAsset = m_assetsToInspect.end(); - - } - - VersionExplorer::~VersionExplorer() - { - AZ::SystemTickBus::Handler::BusDisconnect(); - - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - - } - - void VersionExplorer::Log(const char* format, ...) - { - if (m_ui->verbose->isChecked()) - { - char sBuffer[2048]; - va_list ArgList; - va_start(ArgList, format); - azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); - sBuffer[sizeof(sBuffer) - 1] = '\0'; - va_end(ArgList); - - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); - } - } - - void VersionExplorer::OnClose() - { - reject(); - } - - bool VersionExplorer::IsUpgrading() const - { - return m_inProgressAsset != m_assetsToUpgrade.end() && m_inProgress; - } - - void VersionExplorer::OnSystemTick() - { - switch (m_state) - { - case ProcessState::Scan: - - if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) + if (m_edKeepEditorActive) { - m_inProgress = true; - AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; - m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); - m_currentAsset.BlockUntilLoadComplete(); - if (m_currentAsset.IsReady()) - { - // The asset is ready, grab its info - m_inProgress = true; - InspectAsset(m_currentAsset, assetToUpgrade); - } - else - { - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem - ( tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - ++m_currentAssetRowIndex; + m_keepEditorActive = m_edKeepEditorActive->GetIVal(); + m_edKeepEditorActive->Set(1); + } + } - Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); - ++m_failedAssets; - ScanComplete(m_currentAsset); + EditorKeepAlive::~EditorKeepAlive() + { + if (m_edKeepEditorActive) + { + m_edKeepEditorActive->Set(m_keepEditorActive); + } + } + + View::View(QWidget* parent) + : AzQtComponents::StyledDialog(parent) + , m_ui(new Ui::View()) + { + m_ui->setupUi(this); + m_ui->tableWidget->horizontalHeader()->setVisible(false); + m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + m_ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Fixed); + m_ui->tableWidget->setColumnWidth(3, 22); + m_ui->textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAsNeeded); + m_ui->textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarPolicy::ScrollBarAlwaysOn); + connect(m_ui->scanButton, &QPushButton::pressed, this, &View::OnScanButtonPress); + connect(m_ui->closeButton, &QPushButton::pressed, this, &View::OnCloseButtonPress); + connect(m_ui->upgradeAllButton, &QPushButton::pressed, this, &View::OnUpgradeAllButtonPress); + m_ui->progressBar->setValue(0); + m_ui->progressBar->setVisible(false); + + ViewRequestsBus::Handler::BusConnect(); + ModelNotificationsBus::Handler::BusConnect(); + + // move to model, maybe + m_keepEditorAlive = AZStd::make_unique(); + } + + void View::Log(const char* /*format*/, ...) + { +// if (m_ui->verbose->isChecked()) +// { +// char sBuffer[2048]; +// va_list ArgList; +// va_start(ArgList, format); +// azvsnprintf(sBuffer, sizeof(sBuffer), format, ArgList); +// sBuffer[sizeof(sBuffer) - 1] = '\0'; +// va_end(ArgList); +// +// AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "%s\n", sBuffer); +// } + } + + void View::OnCloseButtonPress() + { + reject(); + } + + void View::OnSystemTick() + { +// switch (m_state) +// { +// case ProcessState::Scan: +// +// if (!m_inProgress && m_inspectingAsset != m_assetsToInspect.end()) +// { +// m_inProgress = true; +// AZ::Data::AssetInfo& assetToUpgrade = *m_inspectingAsset; +// m_currentAsset = AZ::Data::AssetManager::Instance().GetAsset(assetToUpgrade.m_assetId, assetToUpgrade.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); +// Log("SystemTick::ProcessState::Scan: %s pre-blocking load hint", m_currentAsset.GetHint().c_str()); +// m_currentAsset.BlockUntilLoadComplete(); +// if (m_currentAsset.IsReady()) +// { +// // The asset is ready, grab its info +// m_inProgress = true; +// InspectAsset(m_currentAsset, assetToUpgrade); +// } +// else +// { +// m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); +// QTableWidgetItem* rowName = new QTableWidgetItem +// (tr(AZStd::string::format("Error: %s", assetToUpgrade.m_relativePath.c_str()).c_str())); +// m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); +// ++m_currentAssetRowIndex; +// +// Log("SystemTick::ProcessState::Scan: %s post-blocking load, problem loading asset", assetToUpgrade.m_relativePath.c_str()); +// ++m_failedAssets; +// ScanComplete(m_currentAsset); +// } +// } +// break; +// +// case ProcessState::Upgrade: +// { +// AZStd::lock_guard lock(m_mutex); +// if (m_upgradeComplete) +// { +// ++m_upgradeAssetIndex; +// m_inProgress = false; +// m_ui->progressBar->setVisible(true); +// m_ui->progressBar->setValue(m_upgradeAssetIndex); +// +// if (m_scriptCanvasEntity) +// { +// m_scriptCanvasEntity->Deactivate(); +// m_scriptCanvasEntity = nullptr; +// } +// +// GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); +// +// if (!m_isUpgradingSingleGraph) +// { +// if (m_inProgressAsset != m_assetsToUpgrade.end()) +// { +// m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); +// } +// +// if (m_inProgressAsset == m_assetsToUpgrade.end()) +// { +// FinalizeUpgrade(); +// } +// } +// else +// { +// m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); +// m_inProgress = false; +// m_state = ProcessState::Inactive; +// // m_settingsCache.reset(); +// AZ::SystemTickBus::Handler::BusDisconnect(); +// +// } +// +// m_isUpgradingSingleGraph = false; +// +// if (m_assetsToUpgrade.empty()) +// { +// m_ui->upgradeAllButton->setEnabled(false); +// } +// +// m_upgradeComplete = false; +// } +// +// if (!IsUpgrading() && m_state == ProcessState::Upgrade) +// { +// AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); +// // Make the backup +// if (errorMessage.empty()) +// { +// Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); +// QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); +// if (!items.isEmpty()) +// { +// for (auto* item : items) +// { +// int row = item->row(); +// AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); +// spinner->SetIsBusy(true); +// } +// } +// +// // Upgrade the graph +// UpgradeGraph(*m_inProgressAsset); +// } +// else +// { +// Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); +// GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); +// } +// +// } +// break; +// } +// default: +// break; +// } +// +// FlushLogs(); +// +// AZ::Data::AssetManager::Instance().DispatchEvents(); +// AZ::SystemTickBus::ExecuteQueuedEvents(); + } + + // Backup + + void View::OnUpgradeAllButtonPress() + { + m_state = ProcessState::Upgrade; + //m_settingsCache = AZStd::make_unique(); + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + ScriptCanvas::Grammar::g_printAbstractCodeModel = false; + ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; + AZ::Interface::Get()->SetIsUpgrading(true); + AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); + m_inProgressAsset = m_assetsToUpgrade.begin(); + AZ::SystemTickBus::Handler::BusConnect(); + m_ui->progressBar->setVisible(true); + m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); + m_ui->progressBar->setValue(m_upgradeAssetIndex); + m_keepEditorAlive = AZStd::make_unique(); + } + + AZStd::string View::BackupGraph(const AZ::Data::Asset& asset) + { + if (!m_ui->makeBackupCheckbox->isChecked()) + { + // considered a success + return ""; + } + + QDateTime theTime = QDateTime::currentDateTime(); + QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); + + AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); + char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; + AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); + backupPath = backupPathCStr; + + if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) + { + if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) + { + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); + return "Failed to create backup folder"; } } - break; - case ProcessState::Upgrade: - { - AZStd::lock_guard lock(m_mutex); - if (m_upgradeComplete) + AZStd::string devRoot = "@devroot@"; + AZStd::string devAssets = "@devassets@"; + + char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; + AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); + + char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; + AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); + + AZStd::string relativePath = devAssetsCStr; + AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); + if (relativePath.starts_with("/")) { - ++m_upgradeAssetIndex; - m_inProgress = false; - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - - if (m_scriptCanvasEntity) - { - m_scriptCanvasEntity->Deactivate(); - m_scriptCanvasEntity = nullptr; - } - - GraphUpgradeCompleteUIUpdate(m_upgradeAsset, m_upgradeResult, m_upgradeMessage); - - if (!m_isUpgradingSingleGraph) - { - if (m_inProgressAsset != m_assetsToUpgrade.end()) - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - } - - if (m_inProgressAsset == m_assetsToUpgrade.end()) - { - FinalizeUpgrade(); - } - } - else - { - m_inProgressAsset = m_assetsToUpgrade.erase(m_inProgressAsset); - m_inProgress = false; - m_state = ProcessState::Inactive; - m_settingsCache.reset(); - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - } - - m_isUpgradingSingleGraph = false; - - if (m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(false); - } - - m_upgradeComplete = false; + relativePath = relativePath.substr(1, relativePath.size() - 1); } - if (!IsUpgrading() && m_state == ProcessState::Upgrade) + AZStd::string sourceFilePath; + + AZStd::string watchFolder; + AZ::Data::AssetInfo assetInfo; + bool sourceInfoFound{}; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); + if (sourceInfoFound) { - AZStd::string errorMessage = BackupGraph(*m_inProgressAsset); - // Make the backup - if (errorMessage.empty()) - { - Log("SystemTick::ProcessState::Upgrade: Backup Success %s ", m_inProgressAsset->GetHint().c_str()); - QList items = m_ui->tableWidget->findItems(m_inProgressAsset->GetHint().c_str(), Qt::MatchFlag::MatchExactly); - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - AzQtComponents::StyledBusyLabel* spinner = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnStatus)); - spinner->SetIsBusy(true); - } - } + AZStd::string assetPath; + AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - // Upgrade the graph - UpgradeGraph(*m_inProgressAsset); - } - else - { - Log("SystemTick::ProcessState::Upgrade: Backup Failed %s ", m_inProgressAsset->GetHint().c_str()); - GraphUpgradeComplete(*m_inProgressAsset, OperationResult::Failure, errorMessage); - } - - } - break; - } - default: - break; - } - - FlushLogs(); - - AZ::Data::AssetManager::Instance().DispatchEvents(); - AZ::SystemTickBus::ExecuteQueuedEvents(); - } - - // Backup - - void VersionExplorer::OnUpgradeAll() - { - m_state = ProcessState::Upgrade; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - AZ::Interface::Get()->SetIsUpgrading(true); - AZ::Interface::Get()->ClearGraphsThatNeedUpgrade(); - m_inProgressAsset = m_assetsToUpgrade.begin(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - AZ::SystemTickBus::Handler::BusConnect(); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToUpgrade.size())); - m_ui->progressBar->setValue(m_upgradeAssetIndex); - m_keepEditorAlive = AZStd::make_unique(); - } - - AZStd::string VersionExplorer::BackupGraph(const AZ::Data::Asset& asset) - { - if (!m_ui->makeBackupCheckbox->isChecked()) - { - // considered a success - return ""; - } - - QDateTime theTime = QDateTime::currentDateTime(); - QString subFolder = theTime.toString("yyyy-MM-dd [HH.mm.ss]"); - - AZStd::string backupPath = AZStd::string::format("@devroot@/ScriptCanvas_BACKUP/%s", subFolder.toUtf8().data()); - char backupPathCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(backupPath.c_str(), backupPathCStr, AZ_MAX_PATH_LEN); - backupPath = backupPathCStr; - - if (!AZ::IO::FileIOBase::GetInstance()->Exists(backupPath.c_str())) - { - if (AZ::IO::FileIOBase::GetInstance()->CreatePath(backupPath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Failed to create backup folder %s", backupPath.c_str()); - return "Failed to create backup folder"; - } - } - - AZStd::string devRoot = "@devroot@"; - AZStd::string devAssets = "@devassets@"; - - char devRootCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devRoot.c_str(), devRootCStr, AZ_MAX_PATH_LEN); - - char devAssetsCStr[AZ_MAX_PATH_LEN] = { 0 }; - AZ::IO::FileIOBase::GetInstance()->ResolvePath(devAssets.c_str(), devAssetsCStr, AZ_MAX_PATH_LEN); - - AZStd::string relativePath = devAssetsCStr; - AzFramework::StringFunc::Replace(relativePath, devRootCStr, ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AZStd::string sourceFilePath; - - AZStd::string watchFolder; - AZ::Data::AssetInfo assetInfo; - bool sourceInfoFound{}; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(sourceInfoFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, asset.GetHint().c_str(), assetInfo, watchFolder); - if (sourceInfoFound) - { - AZStd::string assetPath; - AzFramework::StringFunc::Path::Join(watchFolder.c_str(), assetInfo.m_relativePath.c_str(), assetPath); - - sourceFilePath = assetPath; - } - else - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); - return "Failed to find source file"; - } - - devRoot = devRootCStr; - AzFramework::StringFunc::Path::Normalize(devRoot); - - relativePath = sourceFilePath; - AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); - if (relativePath.starts_with("/")) - { - relativePath = relativePath.substr(1, relativePath.size() - 1); - } - - AzFramework::StringFunc::Path::Normalize(relativePath); - AzFramework::StringFunc::Path::Normalize(backupPath); - - AZStd::string targetFilePath = backupPath; - targetFilePath += relativePath; - - if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) - { - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "VersionExplorer::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return "Failed to copy source file to backup location"; - } - - Log("VersionExplorer::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); - return ""; - } - - void VersionExplorer::UpgradeGraph(const AZ::Data::Asset& asset) - { - m_inProgress = true; - m_upgradeComplete = false; - Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); - m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); - m_scriptCanvasEntity = nullptr; - - UpgradeNotifications::Bus::Handler::BusConnect(); - - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" - , azrtti_typeid().template ToString().c_str()); - - if (!scriptCanvasAsset) - { - return; - } - - AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "VersionExplorer::UpgradeGraph The Script Canvas asset must have a valid entity"); - if (!scriptCanvasEntity) - { - return; - } - - AZ::Entity* queryEntity = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); - if (queryEntity) - { - if (queryEntity->GetState() == AZ::Entity::State::Active) - { - queryEntity->Deactivate(); - } - - scriptCanvasEntity = queryEntity; - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) - { - scriptCanvasEntity->Init(); - } - - if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) - { - scriptCanvasEntity->Activate(); - } - - AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - if (graphComponent) - { - m_scriptCanvasEntity = scriptCanvasEntity; - - graphComponent->UpgradeGraph - ( asset - , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate - , m_ui->verbose->isChecked()); - } - } - - AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); - } - - void VersionExplorer::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - if (!fullPathFound) - { - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); - } - - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - this->OnSourceFileReleased(asset); - }); - streamer->QueueRequest(flushRequest); - } - - void VersionExplorer::OnSourceFileReleased(AZ::Data::Asset asset) - { - AZStd::string relativePath, fullPath; - AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); - bool fullPathFound = false; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); - m_tmpFileName.clear(); - AZStd::string tmpFileName; - // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. - // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. - if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); - return; - } - - bool tempSavedSucceeded = false; - AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); - if (fileStream.IsOpen()) - { - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasEditor::ScriptCanvasAssetHandler handler; - tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); - } - - fileStream.Close(); - } - - // attempt to remove temporary file no matter what - m_tmpFileName = tmpFileName; - if (!tempSavedSucceeded) - { - GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); - return; - } - - using SCCommandBus = AzToolsFramework::SourceControlCommandBus; - SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, - [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - constexpr const size_t k_maxAttemps = 10; - - if (!info.IsReadOnly()) - { - PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); + sourceFilePath = assetPath; } else { - if (m_overwriteAll) + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "View::BackupGraph: Failed to find file: %s", asset.GetHint().c_str()); + return "Failed to find source file"; + } + + devRoot = devRootCStr; + AzFramework::StringFunc::Path::Normalize(devRoot); + + relativePath = sourceFilePath; + AzFramework::StringFunc::Replace(relativePath, devRoot.c_str(), ""); + if (relativePath.starts_with("/")) + { + relativePath = relativePath.substr(1, relativePath.size() - 1); + } + + AzFramework::StringFunc::Path::Normalize(relativePath); + AzFramework::StringFunc::Path::Normalize(backupPath); + + AZStd::string targetFilePath = backupPath; + targetFilePath += relativePath; + + if (AZ::IO::FileIOBase::GetInstance()->Copy(sourceFilePath.c_str(), targetFilePath.c_str()) != AZ::IO::ResultCode::Success) + { + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "View::BackupGraph: Error creating backup: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); + return "Failed to copy source file to backup location"; + } + + Log("View::BackupGraph: Backed up: %s ---> %s\n", sourceFilePath.c_str(), targetFilePath.c_str()); + return ""; + } + + void View::UpgradeGraph(const AZ::Data::Asset& asset) + { + m_inProgress = true; + m_upgradeComplete = false; + Log("UpgradeGraph %s ", m_inProgressAsset->GetHint().c_str()); + m_ui->spinner->SetText(QObject::tr("Upgrading: %1").arg(asset.GetHint().c_str())); + m_scriptCanvasEntity = nullptr; + + UpgradeNotifications::Bus::Handler::BusConnect(); + + if (asset.GetType() == azrtti_typeid()) + { + ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); + AZ_Assert(scriptCanvasAsset, "Unable to get the asset of ScriptCanvasAsset, but received type: %s" + , azrtti_typeid().template ToString().c_str()); + + if (!scriptCanvasAsset) + { + return; + } + + AZ::Entity* scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); + AZ_Assert(scriptCanvasEntity, "View::UpgradeGraph The Script Canvas asset must have a valid entity"); + if (!scriptCanvasEntity) + { + return; + } + + AZ::Entity* queryEntity = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(queryEntity, &AZ::ComponentApplicationRequests::FindEntity, scriptCanvasEntity->GetId()); + if (queryEntity) + { + if (queryEntity->GetState() == AZ::Entity::State::Active) + { + queryEntity->Deactivate(); + } + + scriptCanvasEntity = queryEntity; + } + + if (scriptCanvasEntity->GetState() == AZ::Entity::State::Constructed) + { + scriptCanvasEntity->Init(); + } + + if (scriptCanvasEntity->GetState() == AZ::Entity::State::Init) + { + scriptCanvasEntity->Activate(); + } + + AZ_Assert(scriptCanvasEntity->GetState() == AZ::Entity::State::Active, "Graph entity is not active"); + auto graphComponent = scriptCanvasEntity->FindComponent(); + AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); + + if (graphComponent) + { + m_scriptCanvasEntity = scriptCanvasEntity; + + graphComponent->UpgradeGraph + (asset + , m_ui->forceUpgrade->isChecked() ? Graph::UpgradeRequest::Forced : Graph::UpgradeRequest::IfOutOfDate + , m_ui->verbose->isChecked()); + } + } + + AZ_Assert(m_scriptCanvasEntity, "The ScriptCanvas asset should have an entity"); + } + + void View::OnGraphUpgradeComplete(AZ::Data::Asset& asset, bool /*skipped*/ /*= false*/) + { + AZStd::string relativePath, fullPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); + bool fullPathFound = false; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); + if (!fullPathFound) + { + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), false, "Full source path not found for %s", relativePath.c_str()); + } + + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(fullPath); + streamer->SetRequestCompleteCallback(flushRequest, [this, asset]([[maybe_unused]] AZ::IO::FileRequestHandle request) + { + this->OnSourceFileReleased(asset); + }); + streamer->QueueRequest(flushRequest); + } + + void View::OnSourceFileReleased(AZ::Data::Asset asset) + { + AZStd::string relativePath, fullPath; + AZ::Data::AssetCatalogRequestBus::BroadcastResult(relativePath, &AZ::Data::AssetCatalogRequests::GetAssetPathById, asset.GetId()); + bool fullPathFound = false; + AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fullPathFound, &AzToolsFramework::AssetSystemRequestBus::Events::GetFullSourcePathFromRelativeProductPath, relativePath, fullPath); + m_tmpFileName.clear(); + AZStd::string tmpFileName; + // here we are saving the graph to a temp file instead of the original file and then copying the temp file to the original file. + // This ensures that AP will not a get a file change notification on an incomplete graph file causing it to fail processing. Temp files are ignored by AP. + if (!AZ::IO::CreateTempFileName(fullPath.c_str(), tmpFileName)) + { + GraphUpgradeComplete(asset, OperationResult::Failure, "Failure to create temporary file name"); + return; + } + + bool tempSavedSucceeded = false; + AZ::IO::FileIOStream fileStream(tmpFileName.c_str(), AZ::IO::OpenMode::ModeWrite | AZ::IO::OpenMode::ModeText); + if (fileStream.IsOpen()) + { + if (asset.GetType() == azrtti_typeid()) + { + ScriptCanvasEditor::ScriptCanvasAssetHandler handler; + tempSavedSucceeded = handler.SaveAssetData(asset, &fileStream); + } + + fileStream.Close(); + } + + // attempt to remove temporary file no matter what + m_tmpFileName = tmpFileName; + if (!tempSavedSucceeded) + { + GraphUpgradeComplete(asset, OperationResult::Failure, "Save asset data to temporary file failed"); + return; + } + + using SCCommandBus = AzToolsFramework::SourceControlCommandBus; + SCCommandBus::Broadcast(&SCCommandBus::Events::RequestEdit, fullPath.c_str(), true, + [this, asset, fullPath, tmpFileName]([[maybe_unused]] bool success, const AzToolsFramework::SourceControlFileInfo& info) + { + constexpr const size_t k_maxAttemps = 10; + + if (!info.IsReadOnly()) { - AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); } else { - int result = QMessageBox::No; - if (!m_overwriteAll) - { - QMessageBox mb(QMessageBox::Warning, - QObject::tr("Failed to Save Upgraded File"), - QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), - QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); - - result = mb.exec(); - if (result == QMessageBox::YesToAll) - { - m_overwriteAll = true; - } - } - - if (result == QMessageBox::Yes || m_overwriteAll) + if (m_overwriteAll) { AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); } - } - } - }); - } - - void VersionExplorer::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target - , size_t remainingAttempts) - { - VersionExplorerCpp::FileEventHandler fileEventHandler; - - if (remainingAttempts == 0) - { - // all attempts failed, give up - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); - GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); - } - else if (remainingAttempts == 2) - { - // before the final attempt, flush all caches - AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); - streamer->SetRequestCompleteCallback(flushRequest - , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) - { - // Continue saving. - AZ::SystemTickBus::QueueFunction( - [this, asset, remainingAttempts, source, target](){ PerformMove(asset, source, target, remainingAttempts - 1); }); - }); - streamer->QueueRequest(flushRequest); - } - else - { - // the actual move attempt - auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); - if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) - { - m_tmpFileName.clear(); - auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - // Bump the slice asset up in the asset processor's queue. - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); - AZ::SystemTickBus::QueueFunction([this, asset]() + else { - GraphUpgradeComplete(asset, OperationResult::Success, ""); - }); - } - else + int result = QMessageBox::No; + if (!m_overwriteAll) + { + QMessageBox mb(QMessageBox::Warning, + QObject::tr("Failed to Save Upgraded File"), + QObject::tr("The upgraded file could not be saved because the file is read only.\nDo you want to make it writeable and overwrite it?"), + QMessageBox::YesToAll | QMessageBox::Yes | QMessageBox::No, this); + + result = mb.exec(); + if (result == QMessageBox::YesToAll) + { + m_overwriteAll = true; + } + } + + if (result == QMessageBox::Yes || m_overwriteAll) + { + AZ::IO::SystemFile::SetWritable(info.m_filePath.c_str(), true); + PerformMove(asset, tmpFileName, fullPath, k_maxAttemps); + } + } + } + }); + } + + void View::PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target + , size_t remainingAttempts) + { + // ViewCpp::FileEventHandler fileEventHandler; + + if (remainingAttempts == 0) { + // all attempts failed, give up + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s. giving up", target.c_str()); + GraphUpgradeComplete(asset, OperationResult::Failure, "Failed to move updated file from backup to source destination"); + } + else if (remainingAttempts == 2) + { + // before the final attempt, flush all caches AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); auto streamer = AZ::Interface::Get(); - AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); - streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCaches(); + streamer->SetRequestCompleteCallback(flushRequest + , [this, asset, remainingAttempts, source, target]([[maybe_unused]] AZ::IO::FileRequestHandle request) { // Continue saving. - AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); + AZ::SystemTickBus::QueueFunction( + [this, asset, remainingAttempts, source, target]() { PerformMove(asset, source, target, remainingAttempts - 1); }); }); streamer->QueueRequest(flushRequest); } - } - } - - void VersionExplorer::GraphUpgradeComplete - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - AZStd::lock_guard lock(m_mutex); - m_upgradeComplete = true; - m_upgradeResult = result; - m_upgradeMessage = message; - m_upgradeAsset = asset; - - if (!m_tmpFileName.empty()) - { - AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); - AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); - - if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) + else { - AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); - } - } - - if (m_upgradeResult == OperationResult::Failure) - { - AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); - } - - m_tmpFileName.clear(); - } - - void VersionExplorer::GraphUpgradeCompleteUIUpdate - ( const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) - { - QString text = asset.GetHint().c_str(); - QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); - - if (!items.isEmpty()) - { - for (auto* item : items) - { - int row = item->row(); - QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); - QString assetName = asset.GetHint().c_str(); - - if (label->text().compare(assetName) == 0) + // the actual move attempt + auto moveResult = AZ::IO::SmartMove(source.c_str(), target.c_str()); + if (moveResult.GetResultCode() == AZ::IO::ResultCode::Success) { - m_ui->tableWidget->removeCellWidget(row, ColumnAction); - m_ui->tableWidget->removeCellWidget(row, ColumnStatus); - - QToolButton* doneButton = new QToolButton(this); - doneButton->setToolTip("Upgrade complete"); - if (result == OperationResult::Success) + m_tmpFileName.clear(); + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); + // Bump the slice asset up in the asset processor's queue. + AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, target.c_str()); + AZ::SystemTickBus::QueueFunction([this, asset]() { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); - } - else + GraphUpgradeComplete(asset, OperationResult::Success, ""); + }); + } + else + { + AZ_Warning(ScriptCanvas::k_VersionExplorerWindow.data(), false, "moving converted file to source destination failed: %s, trying again", target.c_str()); + auto streamer = AZ::Interface::Get(); + AZ::IO::FileRequestPtr flushRequest = streamer->FlushCache(target.c_str()); + streamer->SetRequestCompleteCallback(flushRequest, [this, asset, source, target, remainingAttempts]([[maybe_unused]] AZ::IO::FileRequestHandle request) { - doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); - doneButton->setToolTip(message.data()); - } - - m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); + // Continue saving. + AZ::SystemTickBus::QueueFunction([this, asset, source, target, remainingAttempts]() { PerformMove(asset, source, target, remainingAttempts - 1); }); + }); + streamer->QueueRequest(flushRequest); } } } - } - void VersionExplorer::FinalizeUpgrade() - { - Log("FinalizeUpgrade!"); - m_inProgress = false; - m_assetsToUpgrade.clear(); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(true); - m_keepEditorAlive.reset(); - m_ui->progressBar->setVisible(false); - - // Manual correction - size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); - if (assetsThatNeedManualInspection > 0) + void View::GraphUpgradeComplete + (const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) { - m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); - } - else - { - m_ui->spinner->SetText("Upgrade complete."); - } + AZStd::lock_guard lock(m_mutex); + m_upgradeComplete = true; + m_upgradeResult = result; + m_upgradeMessage = message; + m_upgradeAsset = asset; - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - AZ::Interface::Get()->SetIsUpgrading(false); - m_settingsCache.reset(); - } - - // Scanning - - void VersionExplorer::OnScan() - { - m_assetsToUpgrade.clear(); - m_assetsToInspect.clear(); - m_ui->tableWidget->setRowCount(0); - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); - m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); - DoScan(); - } - - void VersionExplorer::DoScan() - { - m_state = ProcessState::Scan; - m_settingsCache = AZStd::make_unique(); - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - ScriptCanvas::Grammar::g_printAbstractCodeModel = false; - ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; - - AZ::SystemTickBus::Handler::BusConnect(); - AZ::Debug::TraceMessageBus::Handler::BusConnect(); - - if (!m_assetsToInspect.empty()) - { - m_discoveredAssets = m_assetsToInspect.size(); - m_failedAssets = 0; - m_inspectedAssets = 0; - m_currentAssetRowIndex = 0; - m_ui->progressFrame->setVisible(true); - m_ui->progressBar->setVisible(true); - m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); - m_ui->progressBar->setValue(0); - - m_ui->spinner->SetIsBusy(true); - m_ui->spinner->SetBusyIconSize(32); - - m_ui->scanButton->setEnabled(false); - m_ui->upgradeAllButton->setEnabled(false); - m_ui->onlyShowOutdated->setEnabled(false); - - m_inspectingAsset = m_assetsToInspect.begin(); - m_keepEditorAlive = AZStd::make_unique(); - } - } - - void VersionExplorer::BackupComplete() - { - m_currentAssetRowIndex = 0; - m_ui->progressBar->setValue(0); - DoScan(); - } - - void VersionExplorer::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) - { - Log("InspectAsset: %s", asset.GetHint().c_str()); - AZ::Entity* scriptCanvasEntity = nullptr; - if (asset.GetType() == azrtti_typeid()) - { - ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); - if (!scriptCanvasAsset) + if (!m_tmpFileName.empty()) { - Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); + AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance(); + AZ_Assert(fileIO, "GraphUpgradeComplete: No FileIO instance"); + + if (fileIO->Exists(m_tmpFileName.c_str()) && !fileIO->Remove(m_tmpFileName.c_str())) + { + AZ_TracePrintf(ScriptCanvas::k_VersionExplorerWindow.data(), "Failed to remove temporary file: %s", m_tmpFileName.c_str()); + } + } + + if (m_upgradeResult == OperationResult::Failure) + { + AZ::Interface::Get()->GraphNeedsManualUpgrade(asset.GetId()); + } + + m_tmpFileName.clear(); + } + + void View::GraphUpgradeCompleteUIUpdate + (const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message) + { + QString text = asset.GetHint().c_str(); + QList items = m_ui->tableWidget->findItems(text, Qt::MatchFlag::MatchExactly); + + if (!items.isEmpty()) + { + for (auto* item : items) + { + int row = item->row(); + QTableWidgetItem* label = m_ui->tableWidget->item(row, ColumnAsset); + QString assetName = asset.GetHint().c_str(); + + if (label->text().compare(assetName) == 0) + { + m_ui->tableWidget->removeCellWidget(row, ColumnAction); + m_ui->tableWidget->removeCellWidget(row, ColumnStatus); + + QToolButton* doneButton = new QToolButton(this); + doneButton->setToolTip("Upgrade complete"); + if (result == OperationResult::Success) + { + doneButton->setIcon(QIcon(":/stylesheet/img/UI20/checkmark-menu.svg")); + } + else + { + doneButton->setIcon(QIcon(":/stylesheet/img/UI20/titlebar-close.svg")); + doneButton->setToolTip(message.data()); + } + + m_ui->tableWidget->setCellWidget(row, ColumnStatus, doneButton); + } + } + } + } + + void View::FinalizeUpgrade() + { + Log("FinalizeUpgrade!"); + m_inProgress = false; + m_assetsToUpgrade.clear(); + m_ui->upgradeAllButton->setEnabled(false); + m_ui->onlyShowOutdated->setEnabled(true); + m_keepEditorAlive.reset(); + m_ui->progressBar->setVisible(false); + + // Manual correction + size_t assetsThatNeedManualInspection = AZ::Interface::Get()->GetGraphsThatNeedManualUpgrade().size(); + if (assetsThatNeedManualInspection > 0) + { + m_ui->spinner->SetText("Some graphs will require manual corrections, you will be prompted to review them upon closing this dialog"); + } + else + { + m_ui->spinner->SetText("Upgrade complete."); + } + + AZ::SystemTickBus::Handler::BusDisconnect(); + AZ::Interface::Get()->SetIsUpgrading(false); + //m_settingsCache.reset(); + } + + // Scanning + + void View::OnScanButtonPress() + { + ViewNotificationsBus::Broadcast(&ViewNotificationsTraits::ScanRequested); + +// m_assetsToUpgrade.clear(); +// m_assetsToInspect.clear(); +// m_ui->tableWidget->setRowCount(0); +// m_inspectedAssets = 0; +// m_currentAssetRowIndex = 0; +// IUpgradeRequests* upgradeRequests = AZ::Interface::Get(); +// m_assetsToInspect = upgradeRequests->GetAssetsToUpgrade(); +// DoScan(); + } + + void View::DoScan() + { +// m_state = ProcessState::Scan; +// m_settingsCache = AZStd::make_unique(); +// ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; +// ScriptCanvas::Grammar::g_printAbstractCodeModel = false; +// ScriptCanvas::Grammar::g_saveRawTranslationOuputToFile = false; +// +// AZ::SystemTickBus::Handler::BusConnect(); +// +// if (!m_assetsToInspect.empty()) +// { +// m_discoveredAssets = m_assetsToInspect.size(); +// m_failedAssets = 0; +// m_inspectedAssets = 0; +// m_currentAssetRowIndex = 0; +// m_ui->progressFrame->setVisible(true); +// m_ui->progressBar->setVisible(true); +// m_ui->progressBar->setRange(0, aznumeric_cast(m_assetsToInspect.size())); +// m_ui->progressBar->setValue(0); +// +// m_ui->spinner->SetIsBusy(true); +// m_ui->spinner->SetBusyIconSize(32); +// +// m_ui->scanButton->setEnabled(false); +// m_ui->upgradeAllButton->setEnabled(false); +// m_ui->onlyShowOutdated->setEnabled(false); +// +// m_inspectingAsset = m_assetsToInspect.begin(); +// m_keepEditorAlive = AZStd::make_unique(); +// } + } + + void View::BackupComplete() + { + m_currentAssetRowIndex = 0; + m_ui->progressBar->setValue(0); + DoScan(); + } + + void View::InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo) + { + Log("InspectAsset: %s", asset.GetHint().c_str()); + AZ::Entity* scriptCanvasEntity = nullptr; + if (asset.GetType() == azrtti_typeid()) + { + ScriptCanvasAsset* scriptCanvasAsset = asset.GetAs(); + if (!scriptCanvasAsset) + { + Log("InspectAsset: %s, AsestData failed to return ScriptCanvasAsset", asset.GetHint().c_str()); + return; + } + + scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); + AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); + } + + auto graphComponent = scriptCanvasEntity->FindComponent(); + AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); + + bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); + bool forceUpgrade = m_ui->forceUpgrade->isChecked(); + ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); + + + if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) + { + ScanComplete(asset); + Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); return; } - scriptCanvasEntity = scriptCanvasAsset->GetScriptCanvasEntity(); - AZ_Assert(scriptCanvasEntity, "The Script Canvas asset must have a valid entity"); - } + m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); + QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); + m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - auto graphComponent = scriptCanvasEntity->FindComponent(); - AZ_Assert(graphComponent, "The Script Canvas entity must have a Graph component"); - - bool onlyShowOutdatedGraphs = m_ui->onlyShowOutdated->isChecked(); - bool forceUpgrade = m_ui->forceUpgrade->isChecked(); - ScriptCanvas::VersionData graphVersion = graphComponent->GetVersion(); - - - if (!forceUpgrade && onlyShowOutdatedGraphs && graphVersion.IsLatest()) - { - ScanComplete(asset); - Log("InspectAsset: %s, is at latest", asset.GetHint().c_str()); - return; - } - - m_ui->tableWidget->insertRow(static_cast(m_currentAssetRowIndex)); - QTableWidgetItem* rowName = new QTableWidgetItem(tr(asset.GetHint().c_str())); - m_ui->tableWidget->setItem(static_cast(m_currentAssetRowIndex), static_cast(ColumnAsset), rowName); - - if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) - { - m_assetsToUpgrade.push_back(asset); - - AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); - spinner->SetBusyIconSize(16); - - QPushButton* rowGoToButton = new QPushButton(this); - rowGoToButton->setText("Upgrade"); - rowGoToButton->setEnabled(false); - - connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { - - AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { - // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda - UpgradeSingle(rowGoToButton, spinner, assetInfo); - }); - - AZ::SystemTickBus::ExecuteQueuedEvents(); - - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); - } - - char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; - AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); - AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); - AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); - AZ::StringFunc::Path::Normalize(path); - - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - QByteArray assetNameUtf8 = asset.GetHint().c_str(); - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); - - AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); - - QToolButton* browseButton = new QToolButton(this); - browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); - browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); - - QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); - connect(browseButton, &QPushButton::clicked, [absolutePath] { - AzQtComponents::ShowFileOnDesktop(absolutePath); - }); - - m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); - ScanComplete(asset); - ++m_inspectedAssets; - ++m_currentAssetRowIndex; - } - - void VersionExplorer::UpgradeSingle - ( QPushButton* rowGoToButton - , AzQtComponents::StyledBusyLabel* spinner - , AZ::Data::AssetInfo assetInfo) - { - AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset - ( assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); - - if (asset) - { - asset.BlockUntilLoadComplete(); - - if (asset.IsReady()) + if (forceUpgrade || !graphComponent->GetVersion().IsLatest()) { - AZ::Interface::Get()->SetIsUpgrading(true); - m_isUpgradingSingleGraph = true; - m_logs.clear(); - m_ui->textEdit->clear(); - spinner->SetIsBusy(true); + m_assetsToUpgrade.push_back(asset); + + AzQtComponents::StyledBusyLabel* spinner = new AzQtComponents::StyledBusyLabel(this); + spinner->SetBusyIconSize(16); + + QPushButton* rowGoToButton = new QPushButton(this); + rowGoToButton->setText("Upgrade"); rowGoToButton->setEnabled(false); - m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() - , [asset](const UpgradeAssets::value_type& assetToUpgrade) - { - return assetToUpgrade.GetId() == asset.GetId(); + connect(rowGoToButton, &QPushButton::clicked, [this, spinner, rowGoToButton, assetInfo] { + + AZ::SystemTickBus::QueueFunction([this, rowGoToButton, spinner, assetInfo]() { + // Queue the process state change because we can't connect to the SystemTick bus in a Qt lambda + UpgradeSingle(rowGoToButton, spinner, assetInfo); + }); + + AZ::SystemTickBus::ExecuteQueuedEvents(); + }); - m_state = ProcessState::Upgrade; - AZ::SystemTickBus::Handler::BusConnect(); - } + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnAction), rowGoToButton); + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnStatus), spinner); + } + + char resolvedBuffer[AZ_MAX_PATH_LEN] = { 0 }; + AZStd::string path = AZStd::string::format("@devroot@/%s", asset.GetHint().c_str()); + AZ::IO::FileIOBase::GetInstance()->ResolvePath(path.c_str(), resolvedBuffer, AZ_MAX_PATH_LEN); + AZ::StringFunc::Path::GetFullPath(resolvedBuffer, path); + AZ::StringFunc::Path::Normalize(path); + + bool result = false; + AZ::Data::AssetInfo info; + AZStd::string watchFolder; + QByteArray assetNameUtf8 = asset.GetHint().c_str(); + AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, assetNameUtf8, info, watchFolder); + + AZ_Error(ScriptCanvas::k_VersionExplorerWindow.data(), result, "Failed to locate asset info for '%s'.", assetNameUtf8.constData()); + + QToolButton* browseButton = new QToolButton(this); + browseButton->setToolTip(AzQtComponents::fileBrowserActionName()); + browseButton->setIcon(QIcon(":/stylesheet/img/UI20/browse-edit.svg")); + + QString absolutePath = QDir(watchFolder.c_str()).absoluteFilePath(info.m_relativePath.c_str()); + connect(browseButton, &QPushButton::clicked, [absolutePath] { + AzQtComponents::ShowFileOnDesktop(absolutePath); + }); + + m_ui->tableWidget->setCellWidget(static_cast(m_currentAssetRowIndex), static_cast(ColumnBrowse), browseButton); + ScanComplete(asset); + ++m_inspectedAssets; + ++m_currentAssetRowIndex; } - } - void VersionExplorer::ScanComplete(const AZ::Data::Asset& asset) - { - Log("ScanComplete: %s", asset.GetHint().c_str()); - m_inProgress = false; - m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); - m_ui->scanButton->setEnabled(true); - - m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); - FlushLogs(); - - if (m_inspectingAsset == m_assetsToInspect.end()) + void View::UpgradeSingle + (QPushButton* rowGoToButton + , AzQtComponents::StyledBusyLabel* spinner + , AZ::Data::AssetInfo assetInfo) { - AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); + AZ::Data::Asset asset = AZ::Data::AssetManager::Instance().GetAsset + (assetInfo.m_assetId, assetInfo.m_assetType, AZ::Data::AssetLoadBehavior::PreLoad); + + if (asset) + { + asset.BlockUntilLoadComplete(); + + if (asset.IsReady()) + { + AZ::Interface::Get()->SetIsUpgrading(true); + m_isUpgradingSingleGraph = true; + m_logs.clear(); + m_ui->textEdit->clear(); + spinner->SetIsBusy(true); + rowGoToButton->setEnabled(false); + + m_inProgressAsset = AZStd::find_if(m_assetsToUpgrade.begin(), m_assetsToUpgrade.end() + , [asset](const UpgradeAssets::value_type& assetToUpgrade) + { + return assetToUpgrade.GetId() == asset.GetId(); + }); + + m_state = ProcessState::Upgrade; + AZ::SystemTickBus::Handler::BusConnect(); + } + } + } + + void View::ScanComplete(const AZ::Data::Asset& asset) + { + Log("ScanComplete: %s", asset.GetHint().c_str()); + m_inProgress = false; + m_ui->progressBar->setValue(aznumeric_cast(m_currentAssetRowIndex)); + m_ui->scanButton->setEnabled(true); + + m_inspectingAsset = m_assetsToInspect.erase(m_inspectingAsset); + FlushLogs(); + + if (m_inspectingAsset == m_assetsToInspect.end()) + { + AZ::SystemTickBus::QueueFunction([this]() { FinalizeScan(); }); + + if (!m_assetsToUpgrade.empty()) + { + m_ui->upgradeAllButton->setEnabled(true); + } + } + } + + void View::FinalizeScan() + { + Log("FinalizeScan()"); + + m_ui->spinner->SetIsBusy(false); + m_ui->onlyShowOutdated->setEnabled(true); + + // Enable all the Upgrade buttons + for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) + { + QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); + if (button) + { + button->setEnabled(true); + } + } + + QString spinnerText = QStringLiteral("Scan Complete"); + if (m_assetsToUpgrade.empty()) + { + spinnerText.append(" - No graphs require upgrade!"); + } + else + { + spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" + , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); + } + + + m_ui->spinner->SetText(spinnerText); + m_ui->progressBar->setVisible(false); if (!m_assetsToUpgrade.empty()) { m_ui->upgradeAllButton->setEnabled(true); } + + AZ::SystemTickBus::Handler::BusDisconnect(); + + m_keepEditorAlive.reset(); + //m_settingsCache.reset(); + m_state = ProcessState::Inactive; } - } - void VersionExplorer::FinalizeScan() - { - Log("FinalizeScan()"); - - m_ui->spinner->SetIsBusy(false); - m_ui->onlyShowOutdated->setEnabled(true); - - // Enable all the Upgrade buttons - for (int row = 0; row < m_ui->tableWidget->rowCount(); ++row) + void View::FlushLogs() { - QPushButton* button = qobject_cast(m_ui->tableWidget->cellWidget(row, ColumnAction)); - if (button) + if (m_logs.empty()) { - button->setEnabled(true); + return; } + + const QTextCursor oldCursor = m_ui->textEdit->textCursor(); + QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); + + m_ui->textEdit->moveCursor(QTextCursor::End); + QTextCursor textCursor = m_ui->textEdit->textCursor(); + + while (!m_logs.empty()) + { + auto line = "\n" + m_logs.front(); + + m_logs.pop_front(); + + textCursor.insertText(line.c_str()); + } + + scrollBar->setValue(scrollBar->maximum()); + m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); + } - QString spinnerText = QStringLiteral("Scan Complete"); - if (m_assetsToUpgrade.empty()) + + void View::closeEvent(QCloseEvent* event) { - spinnerText.append(" - No graphs require upgrade!"); + m_keepEditorAlive.reset(); + + AzQtComponents::StyledDialog::closeEvent(event); } - else - { - spinnerText.append(QString::asprintf(" - Discovered: %zu, Inspected: %zu, Failed: %zu, Upgradeable: %zu" - , m_discoveredAssets, m_inspectedAssets, m_failedAssets, m_assetsToUpgrade.size())); - } - - - m_ui->spinner->SetText(spinnerText); - m_ui->progressBar->setVisible(false); - - if (!m_assetsToUpgrade.empty()) - { - m_ui->upgradeAllButton->setEnabled(true); - } - - AZ::SystemTickBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - UpgradeNotifications::Bus::Handler::BusDisconnect(); - - m_keepEditorAlive.reset(); - m_settingsCache.reset(); - m_state = ProcessState::Inactive; } - void VersionExplorer::FlushLogs() - { - if (m_logs.empty()) - { - return; - } - - const QTextCursor oldCursor = m_ui->textEdit->textCursor(); - QScrollBar* scrollBar = m_ui->textEdit->verticalScrollBar(); - - m_ui->textEdit->moveCursor(QTextCursor::End); - QTextCursor textCursor = m_ui->textEdit->textCursor(); - - while (!m_logs.empty()) - { - auto line = "\n" + m_logs.front(); - - m_logs.pop_front(); - - textCursor.insertText(line.c_str()); - } - - scrollBar->setValue(scrollBar->maximum()); - m_ui->textEdit->moveCursor(QTextCursor::StartOfLine); - - } - - bool VersionExplorer::CaptureLogFromTraceBus(const char* window, const char* message) - { - if (m_ui->updateReportingOnly->isChecked() && window != ScriptCanvas::k_VersionExplorerWindow) - { - return true; - } - - AZStd::string msg = message; - if (msg.ends_with("\n")) - { - msg = msg.substr(0, msg.size() - 1); - } - - m_logs.push_back(msg); - return m_ui->updateReportingOnly->isChecked(); - } - - bool VersionExplorer::OnPreError(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Error): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorer::OnPreWarning(const char* window, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* message) - { - AZStd::string msg = AZStd::string::format("(Warning): %s", message); - return CaptureLogFromTraceBus(window, msg.c_str()); - } - - bool VersionExplorer::OnException(const char* message) - { - AZStd::string msg = AZStd::string::format("(Exception): %s", message); - return CaptureLogFromTraceBus("Script Canvas", msg.c_str()); - } - - bool VersionExplorer::OnPrintf(const char* window, const char* message) - { - return CaptureLogFromTraceBus(window, message); - } - - void VersionExplorer::closeEvent(QCloseEvent* event) - { - m_keepEditorAlive.reset(); - - AzQtComponents::StyledDialog::closeEvent(event); - } - -#include +#include } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.h index 7ce1920dbb..905074d17e 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.h +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.h @@ -15,7 +15,6 @@ AZ_PUSH_DISABLE_WARNING(4244 4251 4800, "-Wunknown-warning-option") AZ_POP_DISABLE_WARNING #include #include -#include #include #include #include @@ -23,11 +22,14 @@ AZ_POP_DISABLE_WARNING #include #endif +#include +#include + class QPushButton; namespace Ui { - class VersionExplorer; + class View; } namespace AzQtComponents @@ -37,140 +39,132 @@ namespace AzQtComponents namespace ScriptCanvasEditor { - //! Scoped utility to set and restore the "ed_KeepEditorActive" CVar in order to allow - //! the upgrade tool to work even if the editor is not in the foreground - class EditorKeepAlive + namespace VersionExplorer { - public: - EditorKeepAlive(); - ~EditorKeepAlive(); - - private: - int m_keepEditorActive; - ICVar* m_edKeepEditorActive; - }; - - //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog - class VersionExplorer - : public AzQtComponents::StyledDialog - , private AZ::SystemTickBus::Handler - , private UpgradeNotifications::Bus::Handler - , private AZ::Debug::TraceMessageBus::Handler - { - Q_OBJECT - - public: - AZ_CLASS_ALLOCATOR(VersionExplorer, AZ::SystemAllocator, 0); - - explicit VersionExplorer(QWidget* parent = nullptr); - ~VersionExplorer(); - - private: - - static constexpr int ColumnAsset = 0; - static constexpr int ColumnAction = 1; - static constexpr int ColumnBrowse = 2; - static constexpr int ColumnStatus = 3; - - void OnScan(); - void OnClose(); - - enum class ProcessState + //! Scoped utility to set and restore the "ed_KeepEditorActive" CVar in order to allow + //! the upgrade tool to work even if the editor is not in the foreground + class EditorKeepAlive { - Inactive, - Backup, - Scan, - Upgrade, - }; - ProcessState m_state = ProcessState::Inactive; + public: + EditorKeepAlive(); + ~EditorKeepAlive(); - void DoScan(); - void ScanComplete(const AZ::Data::Asset&); - - void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - - void OnUpgradeAll(); - - // SystemTickBus::Handler - void OnSystemTick() override; - // - - // AZ::Debug::TranceMessageBus::Handler - bool OnException(const char* /*message*/) override; - bool OnPrintf(const char* /*window*/, const char* /*message*/) override; - bool OnPreError(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - bool OnPreWarning(const char* /*window*/, const char* /*fileName*/, int /*line*/, const char* /*func*/, const char* /*message*/) override; - // - - bool CaptureLogFromTraceBus(const char* window, const char* message); - - enum class OperationResult - { - Success, - Failure, + private: + int m_keepEditorActive; + ICVar* m_edKeepEditorActive; }; - void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); + //! A tool that collects and upgrades all Script Canvas graphs in the asset catalog + //! Handles display change notifications, handles state change notifications, sends control requests + class View + : public AzQtComponents::StyledDialog + , private AZ::SystemTickBus::Handler + , private UpgradeNotifications::Bus::Handler + , private ViewRequestsBus::Handler + , private ModelNotificationsBus::Handler + { + Q_OBJECT - bool IsUpgrading() const; + public: + AZ_CLASS_ALLOCATOR(View, AZ::SystemAllocator, 0); - bool m_inProgress = false; - // scan fields - size_t m_currentAssetRowIndex = 0; - size_t m_inspectedAssets = 0; - size_t m_failedAssets = 0; - size_t m_discoveredAssets = 0; + explicit View(QWidget* parent = nullptr); + + private: - IUpgradeRequests::AssetList m_assetsToInspect; - IUpgradeRequests::AssetList::iterator m_inspectingAsset; - using UpgradeAssets = AZStd::vector>; - UpgradeAssets m_assetsToUpgrade; - UpgradeAssets::iterator m_inProgressAsset; + static constexpr int ColumnAsset = 0; + static constexpr int ColumnAction = 1; + static constexpr int ColumnBrowse = 2; + static constexpr int ColumnStatus = 3; - AZ::Data::Asset m_currentAsset; + void OnCloseButtonPress(); + void OnScanButtonPress(); + void OnUpgradeAllButtonPress(); - AZStd::unique_ptr m_ui; + enum class ProcessState + { + Inactive, + Backup, + Scan, + Upgrade, + }; + ProcessState m_state = ProcessState::Inactive; - AZStd::unique_ptr m_settingsCache; + void DoScan(); + void ScanComplete(const AZ::Data::Asset&); - // upgrade fields - AZStd::recursive_mutex m_mutex; - bool m_upgradeComplete = false; - AZ::Data::Asset m_upgradeAsset; - int m_upgradeAssetIndex = 0; - OperationResult m_upgradeResult; - AZStd::string m_upgradeMessage; - AZStd::string m_tmpFileName; + void InspectAsset(AZ::Data::Asset& asset, AZ::Data::AssetInfo& assetInfo); - AZStd::unique_ptr m_keepEditorAlive; + // SystemTickBus::Handler + void OnSystemTick() override; - AZStd::deque m_logs; + enum class OperationResult + { + Success, + Failure, + }; - AZ::Entity* m_scriptCanvasEntity = nullptr; + void GraphUpgradeComplete(const AZ::Data::Asset, OperationResult result, AZStd::string_view message); - bool m_isUpgradingSingleGraph = false; + bool IsUpgrading() const { return false; } - void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); + bool m_inProgress = false; + // scan fields + size_t m_currentAssetRowIndex = 0; + size_t m_inspectedAssets = 0; + size_t m_failedAssets = 0; + size_t m_discoveredAssets = 0; - void FlushLogs(); + IUpgradeRequests::AssetList m_assetsToInspect; + IUpgradeRequests::AssetList::iterator m_inspectingAsset; + using UpgradeAssets = AZStd::vector>; + UpgradeAssets m_assetsToUpgrade; + UpgradeAssets::iterator m_inProgressAsset; - void FinalizeUpgrade(); - void FinalizeScan(); + AZ::Data::Asset m_currentAsset; - void BackupComplete(); - AZStd::string BackupGraph(const AZ::Data::Asset&); - void UpgradeGraph(const AZ::Data::Asset&); + AZStd::unique_ptr m_ui; - void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); - void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; + + // upgrade fields + AZStd::recursive_mutex m_mutex; + bool m_upgradeComplete = false; + AZ::Data::Asset m_upgradeAsset; + int m_upgradeAssetIndex = 0; + OperationResult m_upgradeResult; + AZStd::string m_upgradeMessage; + AZStd::string m_tmpFileName; - void OnSourceFileReleased(AZ::Data::Asset asset); + AZStd::unique_ptr m_keepEditorAlive; - void closeEvent(QCloseEvent* event) override; + AZStd::deque m_logs; - bool m_overwriteAll = false; - void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); + AZ::Entity* m_scriptCanvasEntity = nullptr; - void Log(const char* format, ...); - }; + bool m_isUpgradingSingleGraph = false; + + void UpgradeSingle(QPushButton* item, AzQtComponents::StyledBusyLabel* spinner, AZ::Data::AssetInfo assetInfo); + + void FlushLogs(); + + void FinalizeUpgrade(); + void FinalizeScan(); + + void BackupComplete(); + AZStd::string BackupGraph(const AZ::Data::Asset&); + void UpgradeGraph(const AZ::Data::Asset&); + + void GraphUpgradeCompleteUIUpdate(const AZ::Data::Asset asset, OperationResult result, AZStd::string_view message); + void OnGraphUpgradeComplete(AZ::Data::Asset&, bool skipped = false) override; + + void OnSourceFileReleased(AZ::Data::Asset asset); + + void closeEvent(QCloseEvent* event) override; + + bool m_overwriteAll = false; + void PerformMove(AZ::Data::Asset asset, AZStd::string source, AZStd::string target, size_t remainingAttempts); + + void Log(const char* format, ...); + }; + } } diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.ui b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.ui index 0cd67bcf22..f549c821d6 100644 --- a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.ui +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/View.ui @@ -1,7 +1,7 @@ - VersionExplorer - + View + Qt::WindowModal diff --git a/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ViewTraits.h b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ViewTraits.h new file mode 100644 index 0000000000..7f36e8503d --- /dev/null +++ b/Gems/ScriptCanvas/Code/Editor/View/Windows/Tools/UpgradeTool/ViewTraits.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project. + * For complete copyright and license terms please see the LICENSE at the root of this distribution. + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ +#pragma once + +#include + +namespace ScriptCanvasEditor +{ + namespace VersionExplorer + { + class ViewRequestsTraits : public AZ::EBusTraits + { + public: + // flush logs, or add log text + // set progress update + virtual void ClearProgress() {} + virtual void SetInProgress() {} + }; + using ViewRequestsBus = AZ::EBus; + } +} diff --git a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake index dbffe99afd..eb914ae139 100644 --- a/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake +++ b/Gems/ScriptCanvas/Code/scriptcanvasgem_editor_files.cmake @@ -259,20 +259,24 @@ set(FILES Editor/View/Windows/ScriptCanvasContextMenus.cpp Editor/View/Windows/ScriptCanvasContextMenus.h Editor/View/Windows/ScriptCanvasEditorResources.qrc - Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.h + Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp + Editor/View/Windows/Tools/UpgradeTool/FileSaver.h + Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp + Editor/View/Windows/Tools/UpgradeTool/Modifier.h + Editor/View/Windows/Tools/UpgradeTool/Model.cpp + Editor/View/Windows/Tools/UpgradeTool/Model.h + Editor/View/Windows/Tools/UpgradeTool/ModelTraits.h + Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp + Editor/View/Windows/Tools/UpgradeTool/Scanner.h Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.cpp Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.ui - Editor/View/Windows/Tools/UpgradeTool/Scanner.h - Editor/View/Windows/Tools/UpgradeTool/Scanner.cpp - Editor/View/Windows/Tools/UpgradeTool/Modifier.h - Editor/View/Windows/Tools/UpgradeTool/Modifier.cpp - Editor/View/Windows/Tools/UpgradeTool/FileSaver.h - Editor/View/Windows/Tools/UpgradeTool/FileSaver.cpp - Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.h - Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.cpp - Editor/View/Windows/Tools/UpgradeTool/VersionExplorer.ui - Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h + Editor/View/Windows/Tools/UpgradeTool/View.cpp + Editor/View/Windows/Tools/UpgradeTool/View.h + Editor/View/Windows/Tools/UpgradeTool/View.ui + Editor/View/Windows/Tools/UpgradeTool/ViewTraits.h Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.cpp + Editor/View/Windows/Tools/UpgradeTool/VersionExplorerLog.h + Editor/View/Windows/Tools/UpgradeTool/UpgradeHelper.h Editor/Framework/ScriptCanvasGraphUtilities.inl Editor/Framework/ScriptCanvasGraphUtilities.h Editor/Framework/ScriptCanvasTraceUtilities.h