Merge pull request #1011 from aws-lumberyard-dev/ly-as-sdk/LYN-2948

Integration of the LY as an SDK work
This commit is contained in:
Esteban Papp
2021-05-28 11:30:13 -07:00
committed by GitHub
247 changed files with 6904 additions and 7991 deletions
@@ -14,6 +14,7 @@
#include "ProductAssetTreeItemData.h"
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/Path/Path.h>
#include <AzFramework/StringFunc/StringFunc.h>
namespace AssetProcessor
@@ -159,31 +160,33 @@ namespace AssetProcessor
return;
}
AZ::IO::Path productNamePath(product.m_productName, AZ::IO::PosixPathSeparator);
AZStd::vector<AZStd::string> tokens;
AzFramework::StringFunc::Tokenize(product.m_productName.c_str(), tokens, AZ_CORRECT_DATABASE_SEPARATOR, false, true);
if (tokens.empty())
if (productNamePath.empty())
{
AZ_Warning("AssetProcessor", false, "Product id %d has an invalid name: %s", product.m_productID, product.m_productName.c_str());
return;
}
AssetTreeItem* parentItem = m_root.get();
AZStd::string fullFolderName;
for (int i = 0; i < tokens.size() - 1; ++i)
AZ::IO::Path currentFullFolderPath;
const AZ::IO::PathView filename = productNamePath.Filename();
const AZ::IO::PathView fullPathWithoutFilename = productNamePath.RemoveFilename();
AZStd::fixed_string<AZ::IO::MaxPathLength> currentPath;
for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt)
{
AzFramework::StringFunc::AssetDatabasePath::Join(fullFolderName.c_str(), tokens[i].c_str(), fullFolderName);
AssetTreeItem* nextParent = parentItem->GetChildFolder(tokens[i].c_str());
currentPath = pathIt->FixedMaxPathString();
currentFullFolderPath /= currentPath;
AssetTreeItem* nextParent = parentItem->GetChildFolder(currentPath.c_str());
if (!nextParent)
{
if (!modelIsResetting)
{
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
}
nextParent = parentItem->CreateChild(ProductAssetTreeItemData::MakeShared(nullptr, fullFolderName, tokens[i].c_str(), true, AZ::Uuid::CreateNull()));
m_productToTreeItem[fullFolderName] = nextParent;
nextParent = parentItem->CreateChild(ProductAssetTreeItemData::MakeShared(nullptr, currentFullFolderPath.Native(), currentPath.c_str(), true, AZ::Uuid::CreateNull()));
m_productToTreeItem[currentFullFolderPath.Native()] = nextParent;
// m_productIdToTreeItem is not used for folders, folders don't have product IDs.
if (!modelIsResetting)
@@ -205,12 +208,12 @@ namespace AssetProcessor
if (!modelIsResetting)
{
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
}
AZStd::shared_ptr<ProductAssetTreeItemData> productItemData =
ProductAssetTreeItemData::MakeShared(&product, product.m_productName, tokens[tokens.size() - 1].c_str(), false, sourceId);
ProductAssetTreeItemData::MakeShared(&product, product.m_productName, AZStd::fixed_string<AZ::IO::MaxPathLength>(filename.Native()).c_str(), false, sourceId);
m_productToTreeItem[product.m_productName] =
parentItem->CreateChild(productItemData);
m_productIdToTreeItem[product.m_productID] = m_productToTreeItem[product.m_productName];
@@ -63,8 +63,7 @@ namespace AssetProcessor
}
auto fullPath = AZ::IO::Path(scanFolder.m_scanFolder) / source.m_sourceName;
AZ::IO::Path fullPath = AZ::IO::Path(scanFolder.m_scanFolder, AZ::IO::PosixPathSeparator) / source.m_sourceName;
// It's common for Open 3D Engine game projects and scan folders to be in a subfolder
// of the engine install. To improve readability of the source files, strip out
@@ -78,34 +77,35 @@ namespace AssetProcessor
AzFramework::StringFunc::Replace(fullPath.Native(), m_assetRoot.absolutePath().toUtf8(), "");
}
AZStd::vector<AZStd::string> tokens;
AzFramework::StringFunc::Tokenize(fullPath.c_str(), tokens, AZ_CORRECT_DATABASE_SEPARATOR, false, true);
if (tokens.empty())
if (fullPath.empty())
{
AZ_Warning("AssetProcessor", false, "Source id %s has an invalid name: %s",
source.m_sourceGuid.ToString<AZStd::string>().c_str(), source.m_sourceName.c_str());
AZ_Warning(
"AssetProcessor", false, "Source id %s has an invalid name: %s", source.m_sourceGuid.ToString<AZStd::string>().c_str(),
source.m_sourceName.c_str());
return;
}
QModelIndex newIndicesStart;
AssetTreeItem* parentItem = m_root.get();
AZStd::string fullFolderName;
for (int i = 0; i < tokens.size() - 1; ++i)
AZ::IO::Path currentFullFolderPath;
const AZ::IO::PathView filename = fullPath.Filename();
const AZ::IO::PathView fullPathWithoutFilename = fullPath.RemoveFilename();
AZStd::fixed_string<AZ::IO::MaxPathLength> currentPath;
for (auto pathIt = fullPathWithoutFilename.begin(); pathIt != fullPathWithoutFilename.end(); ++pathIt)
{
AzFramework::StringFunc::AssetDatabasePath::Join(fullFolderName.c_str(), tokens[i].c_str(), fullFolderName);
AssetTreeItem* nextParent = parentItem->GetChildFolder(tokens[i].c_str());
currentPath = pathIt->FixedMaxPathString();
currentFullFolderPath /= currentPath;
AssetTreeItem* nextParent = parentItem->GetChildFolder(currentPath.c_str());
if (!nextParent)
{
if (!modelIsResetting)
{
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
}
nextParent = parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(nullptr, nullptr, fullFolderName, tokens[i].c_str(), true));
m_sourceToTreeItem[fullFolderName] = nextParent;
nextParent = parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(nullptr, nullptr, currentFullFolderPath.Native(), currentPath.c_str(), true));
m_sourceToTreeItem[currentFullFolderPath.Native()] = nextParent;
// Folders don't have source IDs, don't add to m_sourceIdToTreeItem
if (!modelIsResetting)
{
@@ -117,12 +117,12 @@ namespace AssetProcessor
if (!modelIsResetting)
{
QModelIndex parentIndex = parentItem == m_root.get() ? QModelIndex() : createIndex(parentItem->GetRow(), 0, parentItem);
QModelIndex parentIndex = createIndex(parentItem->GetRow(), 0, parentItem);
beginInsertRows(parentIndex, parentItem->getChildCount(), parentItem->getChildCount());
}
m_sourceToTreeItem[source.m_sourceName] =
parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, tokens[tokens.size() - 1].c_str(), false));
parentItem->CreateChild(SourceAssetTreeItemData::MakeShared(&source, &scanFolder, source.m_sourceName, AZStd::fixed_string<AZ::IO::MaxPathLength>(filename.Native()).c_str(), false));
m_sourceIdToTreeItem[source.m_sourceID] = m_sourceToTreeItem[source.m_sourceName];
if (!modelIsResetting)
{
-3
View File
@@ -37,11 +37,8 @@ ly_add_target(
PRIVATE
PY_PACKAGE="${python_package_name}"
INCLUDE_DIRECTORIES
PUBLIC
.
PRIVATE
Source
BUILD_DEPENDENCIES
PRIVATE
3rdParty::Qt::Core
@@ -25,7 +25,7 @@ namespace O3DE::ProjectManager
bool GemInfo::IsValid() const
{
return !m_path.isEmpty() && !m_uuid.IsNull();
return !m_name.isEmpty() && !m_path.isEmpty();
}
QString GemInfo::GetPlatformString(Platform platform)
@@ -64,7 +64,6 @@ namespace O3DE::ProjectManager
QString m_path;
QString m_name = "Unknown Gem Name";
QString m_displayName = "Unknown Gem Name";
AZ::Uuid m_uuid;
QString m_creator = "Unknown Creator";
GemOrigin m_gemOrigin = Local;
bool m_isAdded = false; //! Is the gem currently added and enabled in the project?
@@ -33,8 +33,6 @@ namespace O3DE::ProjectManager
item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
item->setData(gemInfo.m_name, RoleName);
const QString uuidString = gemInfo.m_uuid.ToString<AZStd::string>().c_str();
item->setData(uuidString, RoleUuid);
item->setData(gemInfo.m_creator, RoleCreator);
item->setData(gemInfo.m_gemOrigin, RoleGemOrigin);
item->setData(aznumeric_cast<int>(gemInfo.m_platforms), RolePlatforms);
@@ -53,7 +51,7 @@ namespace O3DE::ProjectManager
appendRow(item);
const QModelIndex modelIndex = index(rowCount()-1, 0);
m_uuidToIndexMap[uuidString] = modelIndex;
m_nameToIndexMap[gemInfo.m_name] = modelIndex;
}
void GemModel::Clear()
@@ -76,11 +74,6 @@ namespace O3DE::ProjectManager
return static_cast<GemInfo::GemOrigin>(modelIndex.data(RoleGemOrigin).toInt());
}
QString GemModel::GetUuidString(const QModelIndex& modelIndex)
{
return modelIndex.data(RoleUuid).toString();
}
GemInfo::Platforms GemModel::GetPlatforms(const QModelIndex& modelIndex)
{
return static_cast<GemInfo::Platforms>(modelIndex.data(RolePlatforms).toInt());
@@ -111,10 +104,10 @@ namespace O3DE::ProjectManager
return modelIndex.data(RoleDocLink).toString();
}
QModelIndex GemModel::FindIndexByUuidString(const QString& uuidString) const
QModelIndex GemModel::FindIndexByNameString(const QString& nameString) const
{
const auto iterator = m_uuidToIndexMap.find(uuidString);
if (iterator != m_uuidToIndexMap.end())
const auto iterator = m_nameToIndexMap.find(nameString);
if (iterator != m_nameToIndexMap.end())
{
return iterator.value();
}
@@ -122,11 +115,11 @@ namespace O3DE::ProjectManager
return {};
}
void GemModel::FindGemNamesByUuidStrings(QStringList& inOutGemNames)
void GemModel::FindGemNamesByNameStrings(QStringList& inOutGemNames)
{
for (QString& dependingGemString : inOutGemNames)
{
QModelIndex modelIndex = FindIndexByUuidString(dependingGemString);
QModelIndex modelIndex = FindIndexByNameString(dependingGemString);
if (modelIndex.isValid())
{
dependingGemString = GetName(modelIndex);
@@ -147,7 +140,7 @@ namespace O3DE::ProjectManager
return {};
}
FindGemNamesByUuidStrings(result);
FindGemNamesByNameStrings(result);
return result;
}
@@ -164,7 +157,7 @@ namespace O3DE::ProjectManager
return {};
}
FindGemNamesByUuidStrings(result);
FindGemNamesByNameStrings(result);
return result;
}
@@ -33,8 +33,8 @@ namespace O3DE::ProjectManager
void AddGem(const GemInfo& gemInfo);
void Clear();
QModelIndex FindIndexByUuidString(const QString& uuidString) const;
void FindGemNamesByUuidStrings(QStringList& inOutGemNames);
QModelIndex FindIndexByNameString(const QString& nameString) const;
void FindGemNamesByNameStrings(QStringList& inOutGemNames);
QStringList GetDependingGemUuids(const QModelIndex& modelIndex);
QStringList GetDependingGemNames(const QModelIndex& modelIndex);
QStringList GetConflictingGemUuids(const QModelIndex& modelIndex);
@@ -43,7 +43,6 @@ namespace O3DE::ProjectManager
static QString GetName(const QModelIndex& modelIndex);
static QString GetCreator(const QModelIndex& modelIndex);
static GemInfo::GemOrigin GetGemOrigin(const QModelIndex& modelIndex);
static QString GetUuidString(const QModelIndex& modelIndex);
static GemInfo::Platforms GetPlatforms(const QModelIndex& modelIndex);
static GemInfo::Types GetTypes(const QModelIndex& modelIndex);
static QString GetSummary(const QModelIndex& modelIndex);
@@ -59,7 +58,6 @@ namespace O3DE::ProjectManager
enum UserRole
{
RoleName = Qt::UserRole,
RoleUuid,
RoleCreator,
RoleGemOrigin,
RolePlatforms,
@@ -76,7 +74,7 @@ namespace O3DE::ProjectManager
RoleTypes
};
QHash<QString, QModelIndex> m_uuidToIndexMap;
QHash<QString, QModelIndex> m_nameToIndexMap;
QItemSelectionModel* m_selectionModel = nullptr;
};
} // namespace O3DE::ProjectManager
@@ -220,7 +220,7 @@ namespace RedirectOutput
}
} // namespace RedirectOutput
namespace O3DE::ProjectManager
namespace O3DE::ProjectManager
{
PythonBindings::PythonBindings(const AZ::IO::PathView& enginePath)
: m_enginePath(enginePath)
@@ -283,8 +283,11 @@ namespace O3DE::ProjectManager
AZ_Warning("ProjectManagerWindow", result != -1, "Append to sys path failed");
// import required modules
m_registration = pybind11::module::import("cmake.Tools.registration");
m_engineTemplate = pybind11::module::import("cmake.Tools.engine_template");
m_register = pybind11::module::import("o3de.register");
m_manifest = pybind11::module::import("o3de.manifest");
m_engineTemplate = pybind11::module::import("o3de.engine_template");
m_enableGemProject = pybind11::module::import("o3de.enable_gem");
m_disableGemProject = pybind11::module::import("o3de.disable_gem");
return result == 0 && !PyErr_Occurred();
} catch ([[maybe_unused]] const std::exception& e)
@@ -326,30 +329,30 @@ namespace O3DE::ProjectManager
}
}
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
AZ::Outcome<EngineInfo> PythonBindings::GetEngineInfo()
{
EngineInfo engineInfo;
bool result = ExecuteWithLock([&] {
pybind11::str enginePath = m_registration.attr("get_this_engine_path")();
pybind11::str enginePath = m_manifest.attr("get_this_engine_path")();
auto o3deData = m_registration.attr("load_o3de_manifest")();
auto o3deData = m_manifest.attr("load_o3de_manifest")();
if (pybind11::isinstance<pybind11::dict>(o3deData))
{
engineInfo.m_path = Py_To_String(enginePath);
engineInfo.m_defaultGemsFolder = Py_To_String(o3deData["default_gems_folder"]);
engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]);
engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]);
engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]);
engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"third_party_path","");
engineInfo.m_path = Py_To_String(enginePath);
engineInfo.m_defaultGemsFolder = Py_To_String(o3deData["default_gems_folder"]);
engineInfo.m_defaultProjectsFolder = Py_To_String(o3deData["default_projects_folder"]);
engineInfo.m_defaultRestrictedFolder = Py_To_String(o3deData["default_restricted_folder"]);
engineInfo.m_defaultTemplatesFolder = Py_To_String(o3deData["default_templates_folder"]);
engineInfo.m_thirdPartyPath = Py_To_String_Optional(o3deData,"third_party_path","");
}
auto engineData = m_registration.attr("get_engine_data")(pybind11::none(), enginePath);
auto engineData = m_manifest.attr("get_engine_json_data")(pybind11::none(), enginePath);
if (pybind11::isinstance<pybind11::dict>(engineData))
{
try
{
engineInfo.m_version = Py_To_String_Optional(engineData,"O3DEVersion","0.0.0.0");
engineInfo.m_name = Py_To_String_Optional(engineData,"engine_name","O3DE");
engineInfo.m_version = Py_To_String_Optional(engineData,"O3DEVersion","0.0.0.0");
engineInfo.m_name = Py_To_String_Optional(engineData,"engine_name","O3DE");
}
catch ([[maybe_unused]] const std::exception& e)
{
@@ -364,13 +367,13 @@ namespace O3DE::ProjectManager
}
else
{
return AZ::Success(AZStd::move(engineInfo));
return AZ::Success(AZStd::move(engineInfo));
}
return AZ::Failure();
}
bool PythonBindings::SetEngineInfo(const EngineInfo& engineInfo)
bool PythonBindings::SetEngineInfo(const EngineInfo& engineInfo)
{
bool result = ExecuteWithLock([&] {
pybind11::str enginePath = engineInfo.m_path.toStdString();
@@ -378,17 +381,18 @@ namespace O3DE::ProjectManager
pybind11::str defaultGemsFolder = engineInfo.m_defaultGemsFolder.toStdString();
pybind11::str defaultTemplatesFolder = engineInfo.m_defaultTemplatesFolder.toStdString();
auto registrationResult = m_registration.attr("register")(
enginePath, // engine_path
pybind11::none(), // project_path
pybind11::none(), // gem_path
pybind11::none(), // template_path
pybind11::none(), // restricted_path
pybind11::none(), // repo_uri
pybind11::none(), // default_engines_folder
auto registrationResult = m_register.attr("register")(
enginePath, // engine_path
pybind11::none(), // project_path
pybind11::none(), // gem_path
pybind11::none(), // external_subdir_path
pybind11::none(), // template_path
pybind11::none(), // restricted_path
pybind11::none(), // repo_uri
pybind11::none(), // default_engines_folder
defaultProjectsFolder,
defaultGemsFolder,
defaultTemplatesFolder
defaultGemsFolder,
defaultTemplatesFolder
);
if (registrationResult.cast<int>() != 0)
@@ -396,13 +400,13 @@ namespace O3DE::ProjectManager
result = false;
}
auto manifest = m_registration.attr("load_o3de_manifest")();
auto manifest = m_manifest.attr("load_o3de_manifest")();
if (pybind11::isinstance<pybind11::dict>(manifest))
{
try
{
manifest["third_party_path"] = engineInfo.m_thirdPartyPath.toStdString();
m_registration.attr("save_o3de_manifest")(manifest);
m_manifest.attr("save_o3de_manifest")(manifest);
}
catch ([[maybe_unused]] const std::exception& e)
{
@@ -415,12 +419,12 @@ namespace O3DE::ProjectManager
return result;
}
AZ::Outcome<GemInfo> PythonBindings::GetGem(const QString& path)
AZ::Outcome<GemInfo> PythonBindings::GetGem(const QString& path)
{
GemInfo gemInfo = GemInfoFromPath(pybind11::str(path.toStdString()));
if (gemInfo.IsValid())
{
return AZ::Success(AZStd::move(gemInfo));
return AZ::Success(AZStd::move(gemInfo));
}
else
{
@@ -428,19 +432,19 @@ namespace O3DE::ProjectManager
}
}
AZ::Outcome<QVector<GemInfo>> PythonBindings::GetGems()
AZ::Outcome<QVector<GemInfo>> PythonBindings::GetGems()
{
QVector<GemInfo> gems;
bool result = ExecuteWithLock([&] {
// external gems
for (auto path : m_registration.attr("get_gems")())
// external gems
for (auto path : m_manifest.attr("get_gems")())
{
gems.push_back(GemInfoFromPath(path));
}
// gems from the engine
for (auto path : m_registration.attr("get_engine_gems")())
// gems from the engine
for (auto path : m_manifest.attr("get_engine_gems")())
{
gems.push_back(GemInfoFromPath(path));
}
@@ -452,7 +456,7 @@ namespace O3DE::ProjectManager
}
else
{
return AZ::Success(AZStd::move(gems));
return AZ::Success(AZStd::move(gems));
}
}
@@ -463,7 +467,7 @@ namespace O3DE::ProjectManager
[&]
{
pybind11::str projectPath = path.toStdString();
auto pythonRegistrationResult = m_registration.attr("register")(pybind11::none(), projectPath);
auto pythonRegistrationResult = m_register.attr("register")(pybind11::none(), projectPath);
// Returns an exit code so boolify it then invert result
registrationResult = !pythonRegistrationResult.cast<bool>();
@@ -479,19 +483,23 @@ namespace O3DE::ProjectManager
[&]
{
pybind11::str projectPath = path.toStdString();
auto pythonRegistrationResult = m_registration.attr("register")(
auto pythonRegistrationResult = m_register.attr("register")(
pybind11::none(), // engine_path
projectPath, // project_path
pybind11::none(), // gem_path
pybind11::none(), // external_subdir_path
pybind11::none(), // template_path
pybind11::none(), // restricted_path
pybind11::none(), // repo_uri
pybind11::none(), // default_engines_folder
pybind11::none(), // default_projects_folder
pybind11::none(), // default_gems_folder
pybind11::none(), // default_templates_folder
pybind11::none(), // default_restricted_folder
pybind11::none(), // default_restricted_folder
true // remove
pybind11::none(), // external_subdir_engine_path
pybind11::none(), // external_subdir_project_path
true, // remove
false // force
);
// Returns an exit code so boolify it then invert result
@@ -501,7 +509,7 @@ namespace O3DE::ProjectManager
return result && registrationResult;
}
AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo)
AZ::Outcome<ProjectInfo> PythonBindings::CreateProject(const QString& projectTemplatePath, const ProjectInfo& projectInfo)
{
ProjectInfo createdProjectInfo;
bool result = ExecuteWithLock([&] {
@@ -521,16 +529,16 @@ namespace O3DE::ProjectManager
}
else
{
return AZ::Success(AZStd::move(createdProjectInfo));
return AZ::Success(AZStd::move(createdProjectInfo));
}
}
AZ::Outcome<ProjectInfo> PythonBindings::GetProject(const QString& path)
AZ::Outcome<ProjectInfo> PythonBindings::GetProject(const QString& path)
{
ProjectInfo projectInfo = ProjectInfoFromPath(pybind11::str(path.toStdString()));
if (projectInfo.IsValid())
{
return AZ::Success(AZStd::move(projectInfo));
return AZ::Success(AZStd::move(projectInfo));
}
else
{
@@ -541,30 +549,21 @@ namespace O3DE::ProjectManager
GemInfo PythonBindings::GemInfoFromPath(pybind11::handle path)
{
GemInfo gemInfo;
gemInfo.m_path = Py_To_String(path);
gemInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_gem_data")(pybind11::none(), path);
auto data = m_manifest.attr("get_gem_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
{
// required
gemInfo.m_name = Py_To_String(data["Name"]);
gemInfo.m_uuid = AZ::Uuid(Py_To_String(data["Uuid"]));
gemInfo.m_name = Py_To_String(data["gem_name"]);
// optional
gemInfo.m_displayName = Py_To_String_Optional(data, "DisplayName", gemInfo.m_name);
gemInfo.m_summary = Py_To_String_Optional(data, "Summary", "");
gemInfo.m_version = Py_To_String_Optional(data, "Version", "");
gemInfo.m_displayName = Py_To_String_Optional(data, "DisplayName", gemInfo.m_name);
gemInfo.m_summary = Py_To_String_Optional(data, "Summary", "");
gemInfo.m_version = Py_To_String_Optional(data, "Version", "");
if (data.contains("Dependencies"))
{
for (auto dependency : data["Dependencies"])
{
const AZ::Uuid uuid = Py_To_String(dependency["Uuid"]);
gemInfo.m_dependingGemUuids.push_back(uuid.ToString<AZStd::string>().c_str());
}
}
if (data.contains("Tags"))
{
for (auto tag : data["Tags"])
@@ -588,13 +587,13 @@ namespace O3DE::ProjectManager
projectInfo.m_path = Py_To_String(path);
projectInfo.m_isNew = false;
auto projectData = m_registration.attr("get_project_data")(pybind11::none(), path);
auto projectData = m_manifest.attr("get_project_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(projectData))
{
try
{
projectInfo.m_projectName = Py_To_String(projectData["project_name"]);
projectInfo.m_displayName = Py_To_String_Optional(projectData,"display_name", projectInfo.m_projectName);
projectInfo.m_projectName = Py_To_String(projectData["project_name"]);
projectInfo.m_displayName = Py_To_String_Optional(projectData,"display_name", projectInfo.m_projectName);
}
catch ([[maybe_unused]] const std::exception& e)
{
@@ -605,19 +604,19 @@ namespace O3DE::ProjectManager
return projectInfo;
}
AZ::Outcome<QVector<ProjectInfo>> PythonBindings::GetProjects()
AZ::Outcome<QVector<ProjectInfo>> PythonBindings::GetProjects()
{
QVector<ProjectInfo> projects;
bool result = ExecuteWithLock([&] {
// external projects
for (auto path : m_registration.attr("get_projects")())
// external projects
for (auto path : m_manifest.attr("get_projects")())
{
projects.push_back(ProjectInfoFromPath(path));
}
// projects from the engine
for (auto path : m_registration.attr("get_engine_projects")())
// projects from the engine
for (auto path : m_manifest.attr("get_engine_projects")())
{
projects.push_back(ProjectInfoFromPath(path));
}
@@ -629,7 +628,7 @@ namespace O3DE::ProjectManager
}
else
{
return AZ::Success(AZStd::move(projects));
return AZ::Success(AZStd::move(projects));
}
}
@@ -639,10 +638,9 @@ namespace O3DE::ProjectManager
pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_registration.attr("add_gem_to_project")(
m_enableGemProject.attr("enable_gem_in_project")(
pybind11::none(), // gem_name
pyGemPath,
pybind11::none(), // gem_target
pybind11::none(), // project_name
pyProjectPath
);
@@ -657,10 +655,9 @@ namespace O3DE::ProjectManager
pybind11::str pyGemPath = gemPath.toStdString();
pybind11::str pyProjectPath = projectPath.toStdString();
m_registration.attr("remove_gem_to_project")(
m_disableGemProject.attr("disable_gem_in_project")(
pybind11::none(), // gem_name
pyGemPath,
pybind11::none(), // gem_target
pybind11::none(), // project_name
pyProjectPath
);
@@ -669,7 +666,7 @@ namespace O3DE::ProjectManager
return result;
}
bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo)
bool PythonBindings::UpdateProject([[maybe_unused]] const ProjectInfo& projectInfo)
{
return false;
}
@@ -677,18 +674,18 @@ namespace O3DE::ProjectManager
ProjectTemplateInfo PythonBindings::ProjectTemplateInfoFromPath(pybind11::handle path)
{
ProjectTemplateInfo templateInfo;
templateInfo.m_path = Py_To_String(path);
templateInfo.m_path = Py_To_String(path);
auto data = m_registration.attr("get_template_data")(pybind11::none(), path);
auto data = m_manifest.attr("get_template_json_data")(pybind11::none(), path);
if (pybind11::isinstance<pybind11::dict>(data))
{
try
{
// required
templateInfo.m_displayName = Py_To_String(data["display_name"]);
templateInfo.m_name = Py_To_String(data["template_name"]);
templateInfo.m_summary = Py_To_String(data["summary"]);
templateInfo.m_displayName = Py_To_String(data["display_name"]);
templateInfo.m_name = Py_To_String(data["template_name"]);
templateInfo.m_summary = Py_To_String(data["summary"]);
// optional
if (data.contains("canonical_tags"))
{
@@ -714,12 +711,12 @@ namespace O3DE::ProjectManager
return templateInfo;
}
AZ::Outcome<QVector<ProjectTemplateInfo>> PythonBindings::GetProjectTemplates()
AZ::Outcome<QVector<ProjectTemplateInfo>> PythonBindings::GetProjectTemplates()
{
QVector<ProjectTemplateInfo> templates;
bool result = ExecuteWithLock([&] {
for (auto path : m_registration.attr("get_project_templates")())
for (auto path : m_manifest.attr("get_project_templates")())
{
templates.push_back(ProjectTemplateInfoFromPath(path));
}
@@ -731,7 +728,7 @@ namespace O3DE::ProjectManager
}
else
{
return AZ::Success(AZStd::move(templates));
return AZ::Success(AZStd::move(templates));
}
}
}
@@ -12,7 +12,7 @@
#pragma once
#include <PythonBindingsInterface.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/std/parallel/semaphore.h>
// Qt defines slots, which interferes with the use here.
@@ -25,7 +25,7 @@
namespace O3DE::ProjectManager
{
class PythonBindings
class PythonBindings
: public PythonBindingsInterface::Registrar
{
public:
@@ -68,6 +68,9 @@ namespace O3DE::ProjectManager
AZ::IO::FixedMaxPath m_enginePath;
pybind11::handle m_engineTemplate;
AZStd::recursive_mutex m_lock;
pybind11::handle m_registration;
pybind11::handle m_register;
pybind11::handle m_manifest;
pybind11::handle m_enableGemProject;
pybind11::handle m_disableGemProject;
};
}