LYN-2726 Updated the Settings Registry Merge Utils logic to determine

the project root and engine root to fix issues with running the Editor
or AssetProcessor from within the project folder overriding the
project_path with the engine root bootstrap.cfg project_path entry

The order in which the project path is overridden as follows
1. The <engine-root>/bootstrap.cfg is first merged into the Settings
   Registry. Any '/Amazon/AzCore/Bootstrap/project_path' would be used
   if the following steps don't override that key.
2. Followed by general *.setreg/*.setregpatch files being merged into
   the Settings Registry which can override the
   '/Amazon/AzCore/Bootstrap/project_path' key
3. Next a project.json file searched upwards from the current executable
   directory to determine the project path
4. Finally if a command line parameter that overrides the project path
   is supplied it is used instead
This commit is contained in:
mcgarrah
2021-04-15 22:27:11 -05:00
parent 82ca4bf221
commit bff55bd688
11 changed files with 136 additions and 204 deletions
@@ -578,16 +578,6 @@ namespace AzToolsFramework
*/
virtual bool IsEditorInIsolationMode() = 0;
/*!
* Get the engine root path that the current tool is running under.
*/
virtual const char* GetEngineRootPath() const = 0;
/**
* Get the version of the engine the current tools application is running under
*/
virtual const char* GetEngineVersion() const = 0;
/**
* Creates and adds a new entity to the tools application from components which match at least one of the requiredTags
* The tag matching occurs on AZ::Edit::SystemComponentTags attribute from the reflected class data in the serialization context
@@ -224,112 +224,6 @@ namespace AzToolsFramework
} // Internal
#define AZ_MAX_ENGINE_VERSION_LEN 64
// Private Implementation class to manage the engine root and version
// Note: We are not using any AzCore classes because the ToolsApplication
// initialization happens early on, before the Allocators get instantiated,
// so we are using Qt privately instead
class ToolsApplication::EngineConfigImpl
{
private:
friend class ToolsApplication;
typedef QMap<QString, QString> EngineJsonMap;
EngineConfigImpl(const char* logWindow, const char* fileName)
: m_logWindow(logWindow)
, m_fileName(fileName)
{
m_engineRoot[0] = '\0';
m_engineVersion[0] = '\0';
}
char m_engineRoot[AZ_MAX_PATH_LEN];
char m_engineVersion[AZ_MAX_ENGINE_VERSION_LEN];
EngineJsonMap m_engineConfigMap;
const char* m_logWindow;
const char* m_fileName;
// Read an engine configuration into a map of key/value pairs
bool ReadEngineConfigIntoMap(QString engineJsonPath, EngineJsonMap& engineJsonMap)
{
QFile engineJsonFile(engineJsonPath);
if (!engineJsonFile.open(QIODevice::ReadOnly | QIODevice::Text))
{
AZ_Warning(m_logWindow, false, "Unable to open file '%s' in the current root directory", engineJsonPath.toUtf8().data());
return false;
}
QByteArray engineJsonData = engineJsonFile.readAll();
engineJsonFile.close();
QJsonDocument engineJsonDoc(QJsonDocument::fromJson(engineJsonData));
if (engineJsonDoc.isNull())
{
AZ_Warning(m_logWindow, false, "Unable to read file '%s' in the current root directory", engineJsonPath.toUtf8().data());
return false;
}
QJsonObject engineJsonRoot = engineJsonDoc.object();
for (const QString& configKey : engineJsonRoot.keys())
{
QJsonValue configValue = engineJsonRoot[configKey];
if (configValue.isString() || configValue.isDouble())
{
// Only map strings and numbers, ignore every other type
engineJsonMap[configKey] = configValue.toString();
}
else
{
AZ_Warning(m_logWindow, false, "Ignoring key '%s' from '%s', unsupported type.", configKey.toUtf8().data(), engineJsonPath.toUtf8().data());
}
}
return true;
}
// Initialize the engine config object based on the current
bool Initialize(const char* currentEngineRoot)
{
// Start with the app root as the engine root (legacy), but check to see if the engine root
// is external to the app root
azstrncpy(m_engineRoot, AZ_ARRAY_SIZE(m_engineRoot), currentEngineRoot, strlen(currentEngineRoot) + 1);
// From the appRoot, check and see if we can read any external engine reference in engine.json
QString engineJsonFileName = QString(m_fileName);
QString engineJsonFilePath = QDir(currentEngineRoot).absoluteFilePath(engineJsonFileName);
// From the appRoot, check and see if we can read any external engine reference in engine.json
if (!QFile::exists(engineJsonFilePath))
{
AZ_Warning(m_logWindow, false, "Unable to find '%s' in the current app root directory.", m_fileName);
return false;
}
if (!ReadEngineConfigIntoMap(engineJsonFilePath, m_engineConfigMap))
{
AZ_Warning(m_logWindow, false, "Defaulting root engine path to '%s'", currentEngineRoot);
return false;
}
// Read in the local engine version value
auto localEngineVersionValue = m_engineConfigMap.find(QString(AzToolsFramework::Internal::s_engineConfigEngineVersionKey));
QString localEngineVersion(localEngineVersionValue.value());
azstrncpy(m_engineVersion, AZ_ARRAY_SIZE(m_engineVersion), localEngineVersion.toUtf8().data(), localEngineVersion.length() + 1);
return true;
}
const char* GetEngineRoot() const
{
return m_engineRoot;
}
const char* GetEngineVersion() const
{
return m_engineVersion;
}
};
ToolsApplication::ToolsApplication(int* argc, char*** argv)
: AzFramework::Application(argc, argv)
, m_selectionBounds(AZ::Aabb())
@@ -339,7 +233,6 @@ namespace AzToolsFramework
, m_isInIsolationMode(false)
{
ToolsApplicationRequests::Bus::Handler::BusConnect();
m_engineConfigImpl.reset(new ToolsApplication::EngineConfigImpl(AzToolsFramework::Internal::s_startupLogWindow, AzToolsFramework::Internal::s_engineConfigFileName));
m_undoCache.RegisterToUndoCacheInterface();
}
@@ -391,7 +284,6 @@ namespace AzToolsFramework
void ToolsApplication::Start(const Descriptor& descriptor, const StartupParameters& startupParameters/* = StartupParameters()*/)
{
Application::Start(descriptor, startupParameters);
InitializeEngineConfig();
m_editorEntityManager.Start();
@@ -399,14 +291,6 @@ namespace AzToolsFramework
AZ_Assert(m_editorEntityAPI, "ToolsApplication - Could not retrieve instance of EditorEntityAPI");
}
void ToolsApplication::InitializeEngineConfig()
{
if (!m_engineConfigImpl->Initialize(GetEngineRoot()))
{
AZ_Warning(AzToolsFramework::Internal::s_startupLogWindow, false, "Defaulting engine root path to '%s'", GetEngineRoot());
}
}
void ToolsApplication::StartCommon(AZ::Entity* systemEntity)
{
Application::StartCommon(systemEntity);
@@ -1832,16 +1716,6 @@ namespace AzToolsFramework
return m_isInIsolationMode;
}
const char* ToolsApplication::GetEngineRootPath() const
{
return m_engineConfigImpl->GetEngineRoot();
}
const char* ToolsApplication::GetEngineVersion() const
{
return m_engineConfigImpl->GetEngineVersion();
}
void ToolsApplication::CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName)
{
if (!entityName || !entityName[0])
@@ -150,8 +150,6 @@ namespace AzToolsFramework
void EnterEditorIsolationMode() override;
void ExitEditorIsolationMode() override;
bool IsEditorInIsolationMode() override;
const char* GetEngineRootPath() const override;
const char* GetEngineVersion() const override;
void CreateAndAddEntityFromComponentTags(const AZStd::vector<AZ::Crc32>& requiredTags, const char* entityName) override;
@@ -174,7 +172,6 @@ namespace AzToolsFramework
void CreateUndosForDirtyEntities();
void ConsistencyCheckUndoCache();
void InitializeEngineConfig();
AZ::Aabb m_selectionBounds;
EntityIdList m_selectedEntities;
EntityIdList m_highlightedEntities;
@@ -186,9 +183,6 @@ namespace AzToolsFramework
bool m_isInIsolationMode;
EntityIdSet m_isolatedEntityIdSet;
class EngineConfigImpl;
AZStd::unique_ptr<EngineConfigImpl> m_engineConfigImpl;
EditorEntityAPI* m_editorEntityAPI = nullptr;
EditorEntityManager m_editorEntityManager;
@@ -38,6 +38,7 @@ AZ_POP_DISABLE_WARNING
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/Component/ComponentApplicationBus.h>
#include <AzCore/Asset/AssetTypeInfoBus.h>
#include <AzCore/Utils/Utils.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Asset/SimpleAsset.h>
#include <AzFramework/Asset/AssetCatalogBus.h>
@@ -1212,9 +1213,8 @@ namespace AzToolsFramework
if (!QFile::exists(path))
{
const char* engineRoot = nullptr;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
QDir engineDir = engineRoot ? QDir(engineRoot) : QDir::current();
AZ::IO::FixedMaxPathString engineRoot = AZ::Utils::GetEnginePath();
QDir engineDir = !engineRoot.empty() ? QDir(QString(engineRoot.c_str())) : QDir::current();
path = engineDir.absoluteFilePath(iconPath.c_str());
}