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
@@ -178,14 +178,16 @@ namespace AZ
//! on an update to '/Amazon/AzCore/Bootstrap/project_path' key.
struct UpdateProjectSettingsEventHandler
{
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry)
UpdateProjectSettingsEventHandler(AZ::SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
: m_registry{ registry }
, m_commandLine{ commandLine }
{
}
void operator()(AZStd::string_view path, AZ::SettingsRegistryInterface::Type)
{
using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
// #1 Update the project settings when the project path is set
const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) + "/project_path";
AZ::IO::FixedMaxPath newProjectPath;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectPathKey, path)
@@ -194,6 +196,7 @@ namespace AZ
UpdateProjectSettingsFromProjectPath(AZ::IO::PathView(newProjectPath));
}
// #2 Update the project specialization when the project name is set
const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
FixedValueString newProjectName;
if (SettingsRegistryMergeUtils::IsPathAncestorDescendantOrEqual(projectNameKey, path)
@@ -201,6 +204,12 @@ namespace AZ
{
UpdateProjectSpecializationFromProjectName(newProjectName);
}
// #3 Update the ComponentApplication CommandLine instance when the command line settings are merged into the Settings Registry
if (path == AZ::SettingsRegistryMergeUtils::CommandLineValueChangedKey)
{
UpdateCommandLine();
}
}
//! Add the project name as a specialization underneath the /Amazon/AzCore/Settings/Specializations path
@@ -233,10 +242,16 @@ namespace AZ
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(m_registry);
}
void UpdateCommandLine()
{
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(m_registry, m_commandLine);
}
private:
AZ::IO::FixedMaxPath m_oldProjectPath;
AZ::SettingsRegistryInterface::FixedValueString m_oldProjectName;
AZ::SettingsRegistryInterface& m_registry;
AZ::CommandLine& m_commandLine;
};
void ComponentApplication::Descriptor::AllocatorRemapping::Reflect(ReflectContext* context, ComponentApplication* app)
@@ -415,6 +430,12 @@ namespace AZ
// Add the Command Line arguments into the SettingsRegistry
SettingsRegistryMergeUtils::StoreCommandLineToRegistry(*m_settingsRegistry, m_commandLine);
// Add a notifier to update the project_settings when
// 1. The 'project_path' key changes
// 2. The project specialization when the 'project-name' key changes
// 3. The ComponentApplication command line when the command line is stored to the registry
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry, m_commandLine });
// Merge Command Line arguments
constexpr bool executeRegDumpCommands = false;
SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(*m_settingsRegistry, m_commandLine, executeRegDumpCommands);
@@ -429,10 +450,6 @@ namespace AZ
// for the application root.
CalculateAppRoot();
// Add a notifier to update the /Amazon/AzCore/Settings/Specializations
// when the 'project_path' property changes within the SettingsRegistry
m_projectChangedHandler = m_settingsRegistry->RegisterNotifier(UpdateProjectSettingsEventHandler{ *m_settingsRegistry });
// Merge the bootstrap.cfg file into the Settings Registry as soon as the OSAllocator has been created.
SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(*m_settingsRegistry);
SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(*m_settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
@@ -132,23 +132,14 @@ namespace AZ::Internal
AZ::IO::FixedMaxPath ScanUpRootLocator(AZStd::string_view rootFileToLocate)
{
AZStd::fixed_string<AZ::IO::MaxPathLength> executableDir;
if (AZ::Utils::GetExecutableDirectory(executableDir.data(), executableDir.capacity()) == Utils::ExecutablePathResult::Success)
{
// Update the size value of the executable directory fixed string to correctly be the length of the null-terminated string
// stored within it
executableDir.resize_no_construct(AZStd::char_traits<char>::length(executableDir.data()));
}
AZ::IO::FixedMaxPath engineRootCandidate{ executableDir };
AZ::IO::FixedMaxPath rootCandidate{ AZ::Utils::GetExecutableDirectory() };
bool rootPathVisited = false;
do
{
if (AZ::IO::SystemFile::Exists((engineRootCandidate / rootFileToLocate).c_str()))
if (AZ::IO::SystemFile::Exists((rootCandidate / rootFileToLocate).c_str()))
{
return engineRootCandidate;
return rootCandidate;
}
// Note for posix filesystems the parent directory of '/' is '/' and for windows
@@ -156,38 +147,69 @@ namespace AZ::Internal
// Validate that the parent directory isn't itself, that would imply
// that it is the filesystem root path
AZ::IO::PathView parentPath = engineRootCandidate.ParentPath();
rootPathVisited = (engineRootCandidate == parentPath);
AZ::IO::PathView parentPath = rootCandidate.ParentPath();
rootPathVisited = (rootCandidate == parentPath);
// Recurse upwards one directory
engineRootCandidate = AZStd::move(parentPath);
rootCandidate = AZStd::move(parentPath);
} while (!rootPathVisited);
return {};
}
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value)
{
AZ::CommandLine commandLine;
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
AZ::CommandLine::ParamContainer paramContainer;
commandLine.Dump(paramContainer);
auto projectPathOverride = AZStd::string::format(R"(--regset="%.*s=%.*s")",
aznumeric_cast<int>(path.size()), path.data(), aznumeric_cast<int>(value.size()), value.data());
paramContainer.emplace(paramContainer.begin(), AZStd::move(projectPathOverride));
commandLine.Parse(paramContainer);
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
}
} // namespace AZ::Internal
namespace AZ::SettingsRegistryMergeUtils
{
constexpr AZStd::string_view InternalScanUpEngineRootKey{ "/O3DE/Settings/Internal/engine_root_scan_up_path" };
constexpr AZStd::string_view InternalScanUpProjectRootKey{ "/O3DE/Settings/Internal/project_root_scan_up_path" };
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry)
{
AZ::IO::FixedMaxPath engineRoot;
// This is the 'external' engine root key, as in passed from command-line or .setreg files.
auto engineRootKey = SettingsRegistryInterface::FixedValueString::format("%s/engine_path", BootstrapSettingsRootKey);
// Step 1 Run the scan upwards logic once to find the location of the engine.json if it exist
// Once this step is run the {InternalScanUpEngineRootKey} is set in the Settings Registry
// to have this scan logic only run once InternalScanUpEngineRootKey the supplied registry
if (settingsRegistry.GetType(InternalScanUpEngineRootKey) == SettingsRegistryInterface::Type::NoType)
{
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
engineRoot = Internal::ScanUpRootLocator("engine.json");
// Set the {InternalScanUpEngineRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpEngineRootKey, engineRoot.Native());
if (!engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.Native());
// Inject the engine root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, engineRootKey, engineRoot.Native());
return engineRoot;
}
}
// Step 2 check if the engine_path key has been supplied
if (settingsRegistry.Get(engineRoot.Native(), engineRootKey); !engineRoot.empty())
{
return engineRoot;
}
// We can scan up from exe directory to find engine.json, use that for engine root if it exists.
if (engineRoot = Internal::ScanUpRootLocator("engine.json"); !engineRoot.empty())
{
settingsRegistry.Set(engineRootKey, engineRoot.c_str());
return engineRoot;
}
// Step 3 locate the project root and attempt to find the engine root using the registered engine
// for the project in the project.json file
AZ::IO::FixedMaxPath projectRoot = FindProjectRoot(settingsRegistry);
if (projectRoot.empty())
{
@@ -207,16 +229,30 @@ namespace AZ::SettingsRegistryMergeUtils
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry)
{
AZ::IO::FixedMaxPath projectRoot;
// This is the 'external' project root key, as in passed from command-line or .setreg files.
auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
const auto projectRootKey = SettingsRegistryInterface::FixedValueString::format("%s/project_path", BootstrapSettingsRootKey);
// Step 1 Run the scan upwards logic once to find the location of the project.json if it exist
// Once this step is run the {InternalScanUpProjectRootKey} is set in the Settings Registry
// to have this scan logic only run once for the supplied registry
// SettingsRegistryInterface::GetType is used to check if a key is set
if (settingsRegistry.GetType(InternalScanUpProjectRootKey) == SettingsRegistryInterface::Type::NoType)
{
return projectRoot;
projectRoot = Internal::ScanUpRootLocator("project.json");
// Set the {InternalScanUpProjectRootKey} to make sure this code path isn't called again for this settings registry
settingsRegistry.Set(InternalScanUpProjectRootKey, projectRoot.Native());
if (!projectRoot.empty())
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
// Inject the project root into the front of the command line settings
Internal::InjectSettingToCommandLineFront(settingsRegistry, projectRootKey, projectRoot.Native());
return projectRoot;
}
}
if (projectRoot = Internal::ScanUpRootLocator("project.json"); !projectRoot.empty())
// Step 2 Check the project-path key
// This is the project path root key, as in passed from command-line or .setreg files.
if (settingsRegistry.Get(projectRoot.Native(), projectRootKey))
{
settingsRegistry.Set(projectRootKey, projectRoot.c_str());
return projectRoot;
}
@@ -463,18 +499,6 @@ namespace AZ::SettingsRegistryMergeUtils
void MergeSettingsToRegistry_Bootstrap(SettingsRegistryInterface& registry)
{
ConfigParserSettings parserSettings;
parserSettings.m_commentPrefixFunc = [](AZStd::string_view line) -> AZStd::string_view
{
constexpr AZStd::string_view commentPrefixes[]{ "--", ";","#" };
for (AZStd::string_view commentPrefix : commentPrefixes)
{
if (size_t commentOffset = line.find(commentPrefix); commentOffset != AZStd::string_view::npos)
{
return line.substr(0, commentOffset);
}
}
return line;
};
parserSettings.m_registryRootPointerPath = BootstrapSettingsRootKey;
MergeSettingsToRegistry_ConfigFile(registry, "bootstrap.cfg", parserSettings);
}
@@ -807,6 +831,11 @@ namespace AZ::SettingsRegistryMergeUtils
++argumentIndex;
commandLinePath.resize(commandLineRootSize);
}
// This key is used allow Notification Handlers to know when the command line has been updated within the
// registry. The value itself is meaningless. The JSON path of {CommandLineValueChangedKey}
// being passed to the Notification Event Handler indicates that the command line has be updated
registry.Set(CommandLineValueChangedKey, true);
}
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine)
@@ -823,10 +852,16 @@ namespace AZ::SettingsRegistryMergeUtils
}
else if (valueName == "Value" && !value.empty())
{
m_arguments.push_back(value);
// Make sure value types are in quotes in case they start with a command option prefix
m_arguments.push_back(QuoteArgument(value));
}
}
AZStd::string QuoteArgument(AZStd::string_view arg)
{
return !arg.empty() ? AZStd::string::format(R"("%.*s")", aznumeric_cast<int>(arg.size()), arg.data()) : AZStd::string{ arg };
}
// The first parameter is skipped by the ComamndLine::Parse function so initialize
// the container with one empty element
AZ::CommandLine::ParamContainer m_arguments{ 1 };
@@ -57,6 +57,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! Root key for where command line are stored at within the settings registry
inline static constexpr char CommandLineRootKey[] = "/Amazon/AzCore/Runtime/CommandLine";
//! Key set to trigger a notification that the CommandLine has been stored within the settings registry
//! The value of the key has no meaning. Notification Handlers only need to check if the key was supplied
inline static constexpr char CommandLineValueChangedKey[] = "/Amazon/AzCore/Runtime/CommandLineChanged";
//! Root key where raw project settings (project.json) file is merged to settings registry
inline static constexpr char ProjectSettingsRootKey[] = "/Amazon/Project/Settings";
@@ -74,6 +77,20 @@ namespace AZ::SettingsRegistryMergeUtils
//! If it's still not found, attempt to find the project (by similar means) then reconcile the
//! engine root by inspecting project.json and the engine manifest file.
AZ::IO::FixedMaxPath FindEngineRoot(SettingsRegistryInterface& settingsRegistry);
//! The algorithm that is used to find the project root is as follows
//! 1. The first time this function is it performs a upward scan for a project.json file from
//! the executable directory and if found stores that path to an internal key.
//! In the same step it injects the path into the front of list of command line parameters
//! using the --regset="{BootstrapSettingsRootKey}/project_path=<path>" value
//! 2. Next the "{BootstrapSettingsRootKey}/project_path" is checked to see if it has a project path set
//!
//! The order in which the project path settings are overridden proceeds in the following order
//! 1. project_path set in the <engine-root>/bootstrap.cfg file
//! 2. project_path set in a *.setreg/*.setregpatch file
//! 3. project_path found by scanning upwards from the executable directory to the project.json path
//! 4. project_path set on the Command line via either --regset="{BootstrapSettingsRootKey}/project_path=<path>"
//! or --project_path=<path>
AZ::IO::FixedMaxPath FindProjectRoot(SettingsRegistryInterface& settingsRegistry);
//! Query the specializations that will be used when loading the Settings Registry.
@@ -42,8 +42,14 @@ namespace AzFramework::ProjectManager
AZ::CommandLine commandLine;
commandLine.Parse(argc, argv);
AZ::SettingsRegistryImpl settingsRegistry;
// Store the Command line to the Setting Registry
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
// Retrieve Command Line from Settings Registry, it may have been updated by the call to FindEngineRoot()
// in MergeSettingstoRegistry_ConfigFile
AZ::SettingsRegistryMergeUtils::GetCommandLineFromRegistry(settingsRegistry, commandLine);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(settingsRegistry, commandLine, false);
engineRootPath = AZ::SettingsRegistryMergeUtils::FindEngineRoot(settingsRegistry);
projectRootPath = AZ::SettingsRegistryMergeUtils::FindProjectRoot(settingsRegistry);
@@ -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());
}
@@ -20,6 +20,7 @@
// AzCore
#include <AzCore/Asset/AssetManager.h>
#include <AzCore/UserSettings/UserSettingsComponent.h>
#include <AzCore/Utils/Utils.h>
// AzToolsFramework
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
@@ -104,13 +105,9 @@ void AssetEditorWindow::SaveAssetAs(const AZStd::string_view assetPath)
return;
}
const char* engineRoot;
AzToolsFramework::ToolsApplicationRequestBus::BroadcastResult(engineRoot, &AzToolsFramework::ToolsApplicationRequests::GetEngineRootPath);
auto absoluteAssetPath = AZ::IO::FixedMaxPath(AZ::Utils::GetEnginePath()) / assetPath;
AZStd::string absoluteAssetPath;
AzFramework::StringFunc::Path::Join(engineRoot, assetPath.data(), absoluteAssetPath);
if (!m_ui->m_assetEditorWidget->SaveAssetToPath(absoluteAssetPath))
if (!m_ui->m_assetEditorWidget->SaveAssetToPath(absoluteAssetPath.Native()))
{
AZ_Warning("Asset Editor", false, "File was not saved correctly via SaveAssetAs.");
}
+4 -3
View File
@@ -19,6 +19,8 @@
#include <QMessageBox>
#include <QFileDialog>
#include <AzCore/Utils/Utils.h>
// AzToolsFramework
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
@@ -293,9 +295,8 @@ namespace
// If not found try editor folder
if (!CFileUtil::FileExists(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();
QString scriptFolder = engineDir.absoluteFilePath("Editor/Scripts/");
Path::ConvertBackSlashToSlash(scriptFolder);
+4 -3
View File
@@ -18,6 +18,8 @@
#include "ToolBox.h"
#include <AzCore/Utils/Utils.h>
// AzToolsFramework
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
@@ -419,9 +421,8 @@ void CToolBoxManager::Load(QString xmlpath, AmazonToolbar* pToolbar, bool bToolb
}
}
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();
string enginePath = PathUtil::AddSlash(engineDir.absolutePath().toUtf8().data());