Merge branch 'stabilization/2110' into Prism/FixGemCart

This commit is contained in:
AMZN-nggieber
2021-11-17 10:19:47 -08:00
committed by GitHub
261 changed files with 3636 additions and 2112 deletions
@@ -201,7 +201,7 @@ namespace O3DE::ProjectManager
}
// add all the gem repos into the hash
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemRepoGemsInfos();
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemReposGemInfos();
if (allRepoGemInfosResult.IsSuccess())
{
const QVector<GemInfo>& allRepoGemInfos = allRepoGemInfosResult.GetValue();
@@ -378,7 +378,10 @@ namespace O3DE::ProjectManager
{
const QString selectedGemPath = m_gemModel->GetPath(modelIndex);
// Remove gem from gems to be added
const bool wasAdded = GemModel::WasPreviouslyAdded(modelIndex);
const bool wasAddedDependency = GemModel::WasPreviouslyAddedDependency(modelIndex);
// Remove gem from gems to be added to update any dependencies
GemModel::SetIsAdded(*m_gemModel, modelIndex, false);
// Unregister the gem
@@ -406,6 +409,8 @@ namespace O3DE::ProjectManager
// Select remote gem
QModelIndex remoteGemIndex = m_gemModel->FindIndexByNameString(selectedGemName);
GemModel::SetWasPreviouslyAdded(*m_gemModel, remoteGemIndex, wasAdded);
GemModel::SetWasPreviouslyAddedDependency(*m_gemModel, remoteGemIndex, wasAddedDependency);
QModelIndex proxyIndex = m_proxyModel->mapFromSource(remoteGemIndex);
m_proxyModel->GetSelectionModel()->setCurrentIndex(proxyIndex, QItemSelectionModel::ClearAndSelect);
}
@@ -450,7 +455,7 @@ namespace O3DE::ProjectManager
m_gemModel->AddGem(gemInfo);
}
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemRepoGemsInfos();
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& allRepoGemInfosResult = PythonBindingsInterface::Get()->GetAllGemReposGemInfos();
if (allRepoGemInfosResult.IsSuccess())
{
const QVector<GemInfo>& allRepoGemInfos = allRepoGemInfosResult.GetValue();
@@ -544,7 +549,9 @@ namespace O3DE::ProjectManager
const QString& gemPath = GemModel::GetPath(modelIndex);
// make sure any remote gems we added were downloaded successfully
if (GemModel::GetGemOrigin(modelIndex) == GemInfo::Remote && GemModel::GetDownloadStatus(modelIndex) != GemInfo::Downloaded)
const GemInfo::DownloadStatus status = GemModel::GetDownloadStatus(modelIndex);
if (GemModel::GetGemOrigin(modelIndex) == GemInfo::Remote &&
!(status == GemInfo::Downloaded || status == GemInfo::DownloadSuccessful))
{
QMessageBox::critical(
nullptr, "Cannot add gem that isn't downloaded",
@@ -37,7 +37,7 @@ namespace O3DE::ProjectManager
QString m_additionalInfo = "";
QString m_directoryLink = "";
QString m_repoUri = "";
QStringList m_includedGemPaths = {};
QStringList m_includedGemUris = {};
QDateTime m_lastUpdated;
};
} // namespace O3DE::ProjectManager
@@ -8,6 +8,7 @@
#include <GemRepo/GemRepoInspector.h>
#include <GemRepo/GemRepoItemDelegate.h>
#include <PythonBindingsInterface.h>
#include <QFrame>
#include <QLabel>
@@ -60,8 +61,10 @@ namespace O3DE::ProjectManager
// Repo name and url link
m_nameLabel->setText(m_model->GetName(modelIndex));
m_repoLinkLabel->setText(m_model->GetRepoUri(modelIndex));
m_repoLinkLabel->SetUrl(m_model->GetRepoUri(modelIndex));
const QString repoUri = m_model->GetRepoUri(modelIndex);
m_repoLinkLabel->setText(repoUri);
m_repoLinkLabel->SetUrl(repoUri);
// Repo summary
m_summaryLabel->setText(m_model->GetSummary(modelIndex));
@@ -41,7 +41,7 @@ namespace O3DE::ProjectManager
item->setData(gemRepoInfo.m_lastUpdated, RoleLastUpdated);
item->setData(gemRepoInfo.m_path, RolePath);
item->setData(gemRepoInfo.m_additionalInfo, RoleAdditionalInfo);
item->setData(gemRepoInfo.m_includedGemPaths, RoleIncludedGems);
item->setData(gemRepoInfo.m_includedGemUris, RoleIncludedGems);
appendRow(item);
@@ -98,7 +98,7 @@ namespace O3DE::ProjectManager
return modelIndex.data(RolePath).toString();
}
QStringList GemRepoModel::GetIncludedGemPaths(const QModelIndex& modelIndex)
QStringList GemRepoModel::GetIncludedGemUris(const QModelIndex& modelIndex)
{
return modelIndex.data(RoleIncludedGems).toStringList();
}
@@ -118,23 +118,19 @@ namespace O3DE::ProjectManager
QVector<GemInfo> GemRepoModel::GetIncludedGemInfos(const QModelIndex& modelIndex)
{
QVector<GemInfo> allGemInfos;
QStringList repoGemPaths = GetIncludedGemPaths(modelIndex);
QString repoUri = GetRepoUri(modelIndex);
for (const QString& gemPath : repoGemPaths)
const AZ::Outcome<QVector<GemInfo>, AZStd::string>& gemInfosResult = PythonBindingsInterface::Get()->GetGemRepoGemInfos(repoUri);
if (gemInfosResult.IsSuccess())
{
AZ::Outcome<GemInfo> gemInfoResult = PythonBindingsInterface::Get()->GetGemInfo(gemPath);
if (gemInfoResult.IsSuccess())
{
allGemInfos.append(gemInfoResult.GetValue());
}
else
{
QMessageBox::critical(nullptr, tr("Gem Not Found"), tr("Cannot find info for gem %1.").arg(gemPath));
}
return gemInfosResult.GetValue();
}
else
{
QMessageBox::critical(nullptr, tr("Gems not found"), tr("Cannot find info for gems from repo %1").arg(GetName(modelIndex)));
}
return allGemInfos;
return QVector<GemInfo>();
}
bool GemRepoModel::IsEnabled(const QModelIndex& modelIndex)
@@ -39,7 +39,7 @@ namespace O3DE::ProjectManager
static QDateTime GetLastUpdated(const QModelIndex& modelIndex);
static QString GetPath(const QModelIndex& modelIndex);
static QStringList GetIncludedGemPaths(const QModelIndex& modelIndex);
static QStringList GetIncludedGemUris(const QModelIndex& modelIndex);
static QVector<Tag> GetIncludedGemTags(const QModelIndex& modelIndex);
static QVector<GemInfo> GetIncludedGemInfos(const QModelIndex& modelIndex);
@@ -9,12 +9,14 @@
#include <ProjectBuilderController.h>
#include <ProjectBuilderWorker.h>
#include <ProjectButtonWidget.h>
#include <ProjectManagerSettings.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <QMessageBox>
#include <QDesktopServices>
#include <QUrl>
namespace O3DE::ProjectManager
{
ProjectBuilderController::ProjectBuilderController(const ProjectInfo& projectInfo, ProjectButton* projectButton, QWidget* parent)
@@ -27,6 +29,15 @@ namespace O3DE::ProjectManager
m_worker = new ProjectBuilderWorker(m_projectInfo);
m_worker->moveToThread(&m_workerThread);
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry)
{
// Remove key here in case Project Manager crashing while building that causes HandleResults to not be called
QString settingsKey = GetProjectBuiltSuccessfullyKey(m_projectInfo.m_projectName);
settingsRegistry->Remove(settingsKey.toStdString().c_str());
SaveProjectManagerSettings();
}
connect(&m_workerThread, &QThread::finished, m_worker, &ProjectBuilderWorker::deleteLater);
connect(&m_workerThread, &QThread::started, m_worker, &ProjectBuilderWorker::BuildProject);
connect(m_worker, &ProjectBuilderWorker::Done, this, &ProjectBuilderController::HandleResults);
@@ -80,6 +91,8 @@ namespace O3DE::ProjectManager
void ProjectBuilderController::HandleResults(const QString& result)
{
QString settingsKey = GetProjectBuiltSuccessfullyKey(m_projectInfo.m_projectName);
if (!result.isEmpty())
{
if (result.contains(tr("log")))
@@ -109,12 +122,26 @@ namespace O3DE::ProjectManager
emit NotifyBuildProject(m_projectInfo);
}
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry)
{
settingsRegistry->Remove(settingsKey.toStdString().c_str());
SaveProjectManagerSettings();
}
emit Done(false);
return;
}
else
{
m_projectInfo.m_buildFailed = false;
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry)
{
settingsRegistry->Set(settingsKey.toStdString().c_str(), true);
SaveProjectManagerSettings();
}
}
emit Done(true);
@@ -0,0 +1,54 @@
/*
* 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 "ProjectManagerSettings.h"
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/IO/ByteContainerStream.h>
#include <AzCore/Utils/Utils.h>
namespace O3DE::ProjectManager
{
void SaveProjectManagerSettings()
{
auto settingsRegistry = AZ::SettingsRegistry::Get();
AZ::SettingsRegistryMergeUtils::DumperSettings dumperSettings;
dumperSettings.m_prettifyOutput = true;
dumperSettings.m_jsonPointerPrefix = ProjectManagerKeyPrefix;
AZStd::string stringBuffer;
AZ::IO::ByteContainerStream stringStream(&stringBuffer);
if (!AZ::SettingsRegistryMergeUtils::DumpSettingsRegistryToStream(
*settingsRegistry, ProjectManagerKeyPrefix, stringStream, dumperSettings))
{
AZ_Warning("ProjectManager", false, "Could not save Project Manager settings to stream");
return;
}
AZ::IO::FixedMaxPath o3deUserPath = AZ::Utils::GetO3deManifestDirectory();
o3deUserPath /= AZ::SettingsRegistryInterface::RegistryFolder;
o3deUserPath /= "ProjectManager.setreg";
bool saved = false;
constexpr auto configurationMode =
AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY;
AZ::IO::SystemFile outputFile;
if (outputFile.Open(o3deUserPath.c_str(), configurationMode))
{
saved = outputFile.Write(stringBuffer.data(), stringBuffer.size()) == stringBuffer.size();
}
AZ_Warning("ProjectManager", saved, "Unable to save Project Manager registry file to path: %s", o3deUserPath.c_str());
}
QString GetProjectBuiltSuccessfullyKey(const QString& projectName)
{
return QString("%1/Projects/%2/BuiltSuccessfully").arg(ProjectManagerKeyPrefix).arg(projectName);
}
}
@@ -0,0 +1,21 @@
/*
* 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
#if !defined(Q_MOC_RUN)
#include <QString>
#endif
namespace O3DE::ProjectManager
{
static constexpr char ProjectManagerKeyPrefix[] = "/O3DE/ProjectManager";
void SaveProjectManagerSettings();
QString GetProjectBuiltSuccessfullyKey(const QString& projectName);
}
@@ -14,6 +14,7 @@
#include <ProjectUtils.h>
#include <ProjectBuilderController.h>
#include <ScreensCtrl.h>
#include <ProjectManagerSettings.h>
#include <AzQtComponents/Components/FlowLayout.h>
#include <AzCore/Platform.h>
@@ -22,6 +23,7 @@
#include <AzFramework/Process/ProcessCommon.h>
#include <AzFramework/Process/ProcessWatcher.h>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
@@ -269,17 +271,36 @@ namespace O3DE::ProjectManager
// Add any missing project buttons and restore buttons to default state
for (const ProjectInfo& project : projectsVector)
{
ProjectButton* currentButton = nullptr;
if (!m_projectButtons.contains(QDir::toNativeSeparators(project.m_path)))
{
m_projectButtons.insert(QDir::toNativeSeparators(project.m_path), CreateProjectButton(project));
currentButton = CreateProjectButton(project);
m_projectButtons.insert(QDir::toNativeSeparators(project.m_path), currentButton);
}
else
{
auto projectButtonIter = m_projectButtons.find(QDir::toNativeSeparators(project.m_path));
if (projectButtonIter != m_projectButtons.end())
{
projectButtonIter.value()->RestoreDefaultState();
m_projectsFlowLayout->addWidget(projectButtonIter.value());
currentButton = projectButtonIter.value();
currentButton->RestoreDefaultState();
m_projectsFlowLayout->addWidget(currentButton);
}
}
// Check whether project manager has successfully built the project
if (currentButton)
{
auto settingsRegistry = AZ::SettingsRegistry::Get();
bool projectBuiltSuccessfully = false;
if (settingsRegistry)
{
QString settingsKey = GetProjectBuiltSuccessfullyKey(project.m_projectName);
settingsRegistry->Get(projectBuiltSuccessfully, settingsKey.toStdString().c_str());
}
if (!projectBuiltSuccessfully)
{
currentButton->ShowBuildRequired();
}
}
}
@@ -1135,11 +1135,11 @@ namespace O3DE::ProjectManager
gemRepoInfo.m_isEnabled = false;
}
if (data.contains("gem_paths"))
if (data.contains("gems"))
{
for (auto gemPath : data["gem_paths"])
for (auto gemPath : data["gems"])
{
gemRepoInfo.m_includedGemPaths.push_back(Py_To_String(gemPath));
gemRepoInfo.m_includedGemUris.push_back(Py_To_String(gemPath));
}
}
}
@@ -1188,7 +1188,35 @@ namespace O3DE::ProjectManager
return AZ::Success(AZStd::move(gemRepos));
}
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetAllGemRepoGemsInfos()
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetGemRepoGemInfos(const QString& repoUri)
{
QVector<GemInfo> gemInfos;
AZ::Outcome<void, AZStd::string> result = ExecuteWithLockErrorHandling(
[&]
{
auto pyUri = QString_To_Py_String(repoUri);
auto gemPaths = m_repo.attr("get_gem_json_paths_from_cached_repo")(pyUri);
if (pybind11::isinstance<pybind11::set>(gemPaths))
{
for (auto path : gemPaths)
{
GemInfo gemInfo = GemInfoFromPath(path, pybind11::none());
gemInfo.m_downloadStatus = GemInfo::DownloadStatus::NotDownloaded;
gemInfos.push_back(gemInfo);
}
}
});
if (!result.IsSuccess())
{
return AZ::Failure(result.GetError());
}
return AZ::Success(AZStd::move(gemInfos));
}
AZ::Outcome<QVector<GemInfo>, AZStd::string> PythonBindings::GetAllGemReposGemInfos()
{
QVector<GemInfo> gemInfos;
AZ::Outcome<void, AZStd::string> result = ExecuteWithLockErrorHandling(
@@ -65,7 +65,8 @@ namespace O3DE::ProjectManager
bool AddGemRepo(const QString& repoUri) override;
bool RemoveGemRepo(const QString& repoUri) override;
AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() override;
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemRepoGemsInfos() override;
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemRepoGemInfos(const QString& repoUri) override;
AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemReposGemInfos() override;
AZ::Outcome<void, AZStd::string> DownloadGem(const QString& gemName, std::function<void(int, int)> gemProgressCallback, bool force = false) override;
void CancelDownload() override;
bool IsGemUpdateAvaliable(const QString& gemName, const QString& lastUpdated) override;
@@ -217,11 +217,18 @@ namespace O3DE::ProjectManager
*/
virtual AZ::Outcome<QVector<GemRepoInfo>, AZStd::string> GetAllGemRepoInfos() = 0;
/**
* Gathers all gem infos for repos
* @param repoUri the absolute filesystem path or url to the gem repo.
* @return A list of gem infos.
*/
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetGemRepoGemInfos(const QString& repoUri) = 0;
/**
* Gathers all gem infos for all gems registered from repos.
* @return A list of gem infos.
*/
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemRepoGemsInfos() = 0;
virtual AZ::Outcome<QVector<GemInfo>, AZStd::string> GetAllGemReposGemInfos() = 0;
/**
* Downloads and registers a Gem.
@@ -16,6 +16,8 @@
#include <UpdateProjectSettingsScreen.h>
#include <ProjectUtils.h>
#include <DownloadController.h>
#include <ProjectManagerSettings.h>
#include <AzCore/Settings/SettingsRegistry.h>
#include <QDialogButtonBox>
#include <QMessageBox>
@@ -281,6 +283,21 @@ namespace O3DE::ProjectManager
}
}
if (newProjectSettings.m_projectName != m_projectInfo.m_projectName)
{
// update reg key
QString oldSettingsKey = GetProjectBuiltSuccessfullyKey(m_projectInfo.m_projectName);
QString newSettingsKey = GetProjectBuiltSuccessfullyKey(newProjectSettings.m_projectName);
auto settingsRegistry = AZ::SettingsRegistry::Get();
bool projectBuiltSuccessfully = false;
if (settingsRegistry && settingsRegistry->Get(projectBuiltSuccessfully, oldSettingsKey.toStdString().c_str()))
{
settingsRegistry->Set(newSettingsKey.toStdString().c_str(), projectBuiltSuccessfully);
SaveProjectManagerSettings();
}
}
if (!newProjectSettings.m_newPreviewImagePath.isEmpty())
{
if (!ProjectUtils::ReplaceProjectFile(