Merge pull request #410 from aws-lumberyard-dev/ly-sdk/phistere/LYN-2723-Merge

LYN-2723: Fixes issues with bad project or engine paths

Cherry-pick: 6ce7a6d30c57c941459b43c157861df5d9143ae1
main
Eric Phister 5 years ago committed by GitHub
commit fbdd26bbbc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -19,7 +19,6 @@
#include <AzCore/Jobs/JobManagerComponent.h>
#include <AzCore/Serialization/Json/JsonSystemComponent.h>
#include <AzCore/Memory/MemoryComponent.h>
#include <AzCore/NativeUI/NativeUISystemComponent.h>
#include <AzCore/Script/ScriptSystemComponent.h>
#include <AzCore/Slice/SliceComponent.h>
#include <AzCore/Slice/SliceSystemComponent.h>
@ -43,7 +42,6 @@ namespace AZ
AssetManagerComponent::CreateDescriptor(),
UserSettingsComponent::CreateDescriptor(),
Debug::FrameProfilerComponent::CreateDescriptor(),
NativeUI::NativeUISystemComponent::CreateDescriptor(),
SliceComponent::CreateDescriptor(),
SliceSystemComponent::CreateDescriptor(),
SliceMetadataInfoComponent::CreateDescriptor(),

@ -28,6 +28,8 @@
#include <AzCore/Memory/AllocatorManager.h>
#include <AzCore/Memory/MallocSchema.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/Serialization/EditContext.h>
#include <AzCore/Serialization/ObjectStream.h>
#include <AzCore/Serialization/Utils.h>
@ -424,7 +426,7 @@ namespace AZ
// Now that the Allocators are initialized, the Command Line parameters can be parsed
m_commandLine.Parse(m_argC, m_argV);
ParseCommandLine(m_commandLine);
SettingsRegistryMergeUtils::ParseCommandLine(m_commandLine);
// Create the settings registry and register it with the AZ interface system
// This is done after the AppRoot has been calculated so that the Bootstrap.cfg
@ -527,10 +529,42 @@ namespace AZ
DestroyAllocator();
}
void ReportBadEngineRoot()
{
AZStd::string errorMessage = {"Unable to determine a valid path to the engine.\n"
"Check parameters such as --project-path and --engine-path and make sure they are valid.\n"};
if (auto registry = AZ::SettingsRegistry::Get(); registry != nullptr)
{
AZ::SettingsRegistryInterface::FixedValueString filePathErrorStr;
if (registry->Get(filePathErrorStr, AZ::SettingsRegistryMergeUtils::FilePathKey_ErrorText); !filePathErrorStr.empty())
{
errorMessage += "Additional Info:\n";
errorMessage += filePathErrorStr.c_str();
}
}
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI != nullptr)
{
nativeUI->DisplayOkDialog("O3DE Fatal Error", errorMessage.c_str(), false);
}
else
{
AZ_Error("ComponentApplication", false, "O3DE Fatal Error: %s\n", errorMessage.c_str());
}
}
Entity* ComponentApplication::Create(const Descriptor& descriptor, const StartupParameters& startupParameters)
{
AZ_Assert(!m_isStarted, "Component application already started!");
if (m_engineRoot.empty())
{
ReportBadEngineRoot();
return nullptr;
}
m_startupParameters = startupParameters;
m_descriptor = descriptor;
@ -871,46 +905,6 @@ namespace AZ
}
}
void ComponentApplication::ParseCommandLine(const AZ::CommandLine& commandLine)
{
struct OptionKeyToRegsetKey
{
AZStd::string_view m_optionKey;
AZStd::string m_regsetKey;
};
// Provide overrides for the engine root, the project root and the project cache root
AZStd::array commandOptions = {
OptionKeyToRegsetKey{ "engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
OptionKeyToRegsetKey{ "project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) },
OptionKeyToRegsetKey{ "project-cache-path", AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey) }
};
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
for (auto&& [optionKey, regsetKey] : commandOptions)
{
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
{
// Use the last supplied command option value to override previous values
auto overrideArg = AZStd::string::format(R"(--regset="%s=%s")", regsetKey.c_str(),
commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
overrideArgs.emplace_back(AZStd::move(overrideArg));
}
}
if (!overrideArgs.empty())
{
// Dump the input command line, add the additional option overrides
// and Parse the new command line into the Component Application command line
AZ::CommandLine::ParamContainer commandLineArgs;
commandLine.Dump(commandLineArgs);
commandLineArgs.insert(commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()),
AZStd::make_move_iterator(overrideArgs.end()));
m_commandLine.Parse(commandLineArgs);
}
}
void ComponentApplication::MergeSettingsToRegistry(SettingsRegistryInterface& registry)
{
SettingsRegistryInterface::Specializations specializations;

@ -328,9 +328,6 @@ namespace AZ
/// Create the drillers
void CreateDrillers();
/// Parse ComponentApplication specific command line arguments
void ParseCommandLine(const AZ::CommandLine& commandLine);
virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
//! Sets the specializations that will be used when loading the Settings Registry. Extend this in derived

@ -15,45 +15,49 @@
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/string/string.h>
namespace AZ
namespace AZ::NativeUI
{
namespace NativeUI
enum AssertAction
{
enum AssertAction
{
IGNORE_ASSERT = 0,
IGNORE_ALL_ASSERTS,
BREAK,
NONE,
};
class NativeUIRequests
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
using MutexType = AZStd::recursive_mutex;
// Waits for user to select an option before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Displays an assert dialog box
// Returns the action selected by the user
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
};
using NativeUIRequestBus = AZ::EBus<NativeUIRequests>;
}
}
IGNORE_ASSERT = 0,
IGNORE_ALL_ASSERTS,
BREAK,
NONE,
};
class NativeUIRequests
{
public:
AZ_RTTI(NativeUIRequests, "{48361EE6-C1E7-4965-A13A-7425B2691817}");
virtual ~NativeUIRequests() = default;
// Waits for user to select an option before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayBlockingDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, const AZStd::vector<AZStd::string>& /*options*/) const { return ""; };
// Waits for user to select an option ('Ok' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayOkDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Waits for user to select an option ('Yes', 'No' or optionally 'Cancel') before execution continues
// Returns the option string selected by the user
virtual AZStd::string DisplayYesNoDialog(const AZStd::string& /*title*/, const AZStd::string& /*message*/, bool /*showCancel*/) const { return ""; };
// Displays an assert dialog box
// Returns the action selected by the user
virtual AssertAction DisplayAssertDialog(const AZStd::string& /*message*/) const { return AssertAction::NONE; };
};
class NativeUIEBusTraits
: public AZ::EBusTraits
{
public:
//////////////////////////////////////////////////////////////////////////
// EBusTraits overrides
static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single;
static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single;
using MutexType = AZStd::recursive_mutex;
};
using NativeUIRequestBus = AZ::EBus<NativeUIRequests, NativeUIEBusTraits>;
} // namespace AZ::NativeUI

@ -15,50 +15,19 @@
#include <AzCore/NativeUI/NativeUISystemComponent.h>
namespace AZ
namespace AZ::NativeUI
{
using namespace AZ::NativeUI;
void NativeUISystemComponent::Reflect(AZ::ReflectContext* context)
{
if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
{
serialize->Class<NativeUISystemComponent, AZ::Component>()
->Version(0)
;
if (AZ::EditContext* ec = serialize->GetEditContext())
{
ec->Class<NativeUISystemComponent>("NativeUI", "Adds basic support for native (platform specific) UI dialog boxes")
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
;
}
}
}
void NativeUISystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
{
provided.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
}
void NativeUISystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
{
incompatible.push_back(AZ_CRC("NativeUIService", 0x8ec25f87));
}
void NativeUISystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
NativeUISystem::NativeUISystem()
{
(void)required;
NativeUIRequestBus::Handler::BusConnect();
}
void NativeUISystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
NativeUISystem::~NativeUISystem()
{
(void)dependent;
NativeUIRequestBus::Handler::BusDisconnect();
}
AssertAction NativeUISystemComponent::DisplayAssertDialog(const AZStd::string& message) const
AssertAction NativeUISystem::DisplayAssertDialog(const AZStd::string& message) const
{
static const char* buttonNames[3] = { "Ignore", "Ignore All", "Break" };
AZStd::vector<AZStd::string> options;
@ -80,7 +49,7 @@ namespace AZ
return AssertAction::NONE;
}
AZStd::string NativeUISystemComponent::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
AZStd::string NativeUISystem::DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
{
AZStd::vector<AZStd::string> options;
@ -93,7 +62,7 @@ namespace AZ
return DisplayBlockingDialog(title, message, options);
}
AZStd::string NativeUISystemComponent::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
AZStd::string NativeUISystem::DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const
{
AZStd::vector<AZStd::string> options;
@ -106,18 +75,4 @@ namespace AZ
return DisplayBlockingDialog(title, message, options);
}
void NativeUISystemComponent::Init()
{
}
void NativeUISystemComponent::Activate()
{
NativeUIRequestBus::Handler::BusConnect();
}
void NativeUISystemComponent::Deactivate()
{
NativeUIRequestBus::Handler::BusDisconnect();
}
}
} // namespace AZ::NativeUI

@ -15,40 +15,24 @@
#include <AzCore/Component/Component.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
namespace AZ
namespace AZ::NativeUI
{
namespace NativeUI
class NativeUISystem
: public NativeUIRequestBus::Handler
{
class NativeUISystemComponent
: public AZ::Component
, public NativeUIRequestBus::Handler
{
public:
AZ_COMPONENT(NativeUISystemComponent, "{E996C058-4AFE-4C8C-816F-98D864D8576D}");
static void Reflect(AZ::ReflectContext* context);
static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent);
////////////////////////////////////////////////////////////////////////
// NativeUIRequestBus interface implementation
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
////////////////////////////////////////////////////////////////////////
protected:
////////////////////////////////////////////////////////////////////////
// AZ::Component interface implementation
void Init() override;
void Activate() override;
void Deactivate() override;
////////////////////////////////////////////////////////////////////////
};
}
}
public:
AZ_RTTI(NativeUISystem, "{FF534B2C-11BE-4DEA-A5B7-A4FA96FE1EDE}", NativeUIRequests);
AZ_CLASS_ALLOCATOR(NativeUISystem, AZ::OSAllocator, 0);
NativeUISystem();
~NativeUISystem() override;
////////////////////////////////////////////////////////////////////////
// NativeUIRequestBus interface implementation
AZStd::string DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const override;
AZStd::string DisplayOkDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AZStd::string DisplayYesNoDialog(const AZStd::string& title, const AZStd::string& message, bool showCancel) const override;
AssertAction DisplayAssertDialog(const AZStd::string& message) const override;
////////////////////////////////////////////////////////////////////////
};
} // namespace AZ::NativeUI

@ -256,7 +256,7 @@ namespace AZ
//! Remove the value at the provided path
//! @param path The path to a value that should be removed
//! @return Whether or not the value was stored at the provided path. An invalid path will return false;
//! @return Whether or not the path was found and removed. An invalid path will return false;
virtual bool Remove(AZStd::string_view path) = 0;
//! Structure which contains configuration settings for how to parse a single command line argument

@ -32,17 +32,12 @@
namespace AZ::Internal
{
AZ::SettingsRegistryInterface::FixedValueString GetEngineMonikerForProject(
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectPath)
SettingsRegistryInterface& settingsRegistry, const AZ::IO::FixedMaxPath& projectJsonPath)
{
// projectPath needs to be an absolute path here.
using namespace AZ::SettingsRegistryMergeUtils;
bool projectJsonMerged = false;
auto projectJsonPath = projectPath / "project.json";
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
projectJsonMerged = settingsRegistry.MergeSettingsFile(
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
}
bool projectJsonMerged = settingsRegistry.MergeSettingsFile(
projectJsonPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, ProjectSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString engineMoniker;
if (projectJsonMerged)
@ -105,12 +100,12 @@ namespace AZ::Internal
const auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine_name", EngineSettingsRootKey);
AZStd::set<AZ::IO::FixedMaxPath> projectPathsNotFound;
for (EngineInfo& engineInfo : pathVisitor.m_enginePaths)
{
AZ::IO::FixedMaxPath engineSettingsPath{engineInfo.m_path};
engineSettingsPath /= "engine.json";
if (AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
if (auto engineSettingsPath = AZ::IO::FixedMaxPath{engineInfo.m_path} / "engine.json";
AZ::IO::SystemFile::Exists(engineSettingsPath.c_str()))
{
if (settingsRegistry.MergeSettingsFile(
engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineSettingsRootKey))
@ -119,12 +114,61 @@ namespace AZ::Internal
}
}
auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, engineInfo.m_path / projectPath);
if (!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
if (auto projectJsonPath = (engineInfo.m_path / projectPath / "project.json").LexicallyNormal();
AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
engineRoot = engineInfo.m_path;
break;
if (auto engineMoniker = Internal::GetEngineMonikerForProject(settingsRegistry, projectJsonPath);
!engineMoniker.empty() && engineMoniker == engineInfo.m_moniker)
{
engineRoot = engineInfo.m_path;
break;
}
}
else
{
projectPathsNotFound.insert(projectJsonPath);
}
// Continue looking for candidates, remove the previous engine and project settings that were merged above.
settingsRegistry.Remove(ProjectSettingsRootKey);
settingsRegistry.Remove(EngineSettingsRootKey);
}
if (engineRoot.empty())
{
AZStd::string errorStr;
if (!projectPathsNotFound.empty())
{
// This case is usually encountered when a project path is given as a relative path,
// which is assumed to be relative to an engine root.
// When no project.json files are found this way, dump this error message about
// which project paths were checked.
AZStd::string projectPathsTested;
for (const auto& path : projectPathsNotFound)
{
projectPathsTested.append(AZStd::string::format(" %s\n", path.c_str()));
}
errorStr = AZStd::string::format("No valid project was found at these locations:\n%s"
"Please supply a valid --project-path to the application.",
projectPathsTested.c_str());
}
else
{
// The other case is that a project.json was found, but after checking all the registered engines
// none of them matched the engine moniker.
AZStd::string enginePathsChecked;
for (const auto& engineInfo : pathVisitor.m_enginePaths)
{
enginePathsChecked.append(AZStd::string::format(" %s (%s)\n", engineInfo.m_path.c_str(), engineInfo.m_moniker.c_str()));
}
errorStr = AZStd::string::format(
"No engine was found in o3de_manifest.json with a name that matches the one set in the project.json.\n"
"Engines that were checked:\n%s"
"Please check that your engine and project have both been registered with scripts/o3de.py.", enginePathsChecked.c_str()
);
}
settingsRegistry.Set(FilePathKey_ErrorText, errorStr.c_str());
}
}
@ -158,7 +202,7 @@ namespace AZ::Internal
return {};
}
void InjectSettingToCommandLineFront(AZ::SettingsRegistryInterface& settingsRegistry,
void InjectSettingToCommandLineBack(AZ::SettingsRegistryInterface& settingsRegistry,
AZStd::string_view path, AZStd::string_view value)
{
AZ::CommandLine commandLine;
@ -168,7 +212,7 @@ namespace AZ::Internal
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));
paramContainer.emplace(paramContainer.end(), AZStd::move(projectPathOverride));
commandLine.Parse(paramContainer);
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
}
@ -197,8 +241,8 @@ namespace AZ::SettingsRegistryMergeUtils
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());
// Inject the engine root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, engineRootKey, engineRoot.Native());
return engineRoot;
}
}
@ -244,8 +288,8 @@ namespace AZ::SettingsRegistryMergeUtils
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());
// Inject the project root at the end of the command line settings
Internal::InjectSettingToCommandLineBack(settingsRegistry, projectRootKey, projectRoot.Native());
return projectRoot;
}
}
@ -874,6 +918,49 @@ namespace AZ::SettingsRegistryMergeUtils
return true;
}
void ParseCommandLine(AZ::CommandLine& commandLine)
{
struct OptionKeyToRegsetKey
{
AZStd::string_view m_optionKey;
AZStd::string m_regsetKey;
};
// Provide overrides for the engine root, the project root and the project cache root
AZStd::array commandOptions = {
OptionKeyToRegsetKey{
"engine-path", AZStd::string::format("%s/engine_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
OptionKeyToRegsetKey{
"project-path", AZStd::string::format("%s/project_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)},
OptionKeyToRegsetKey{
"project-cache-path",
AZStd::string::format("%s/project_cache_path", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)}};
AZStd::fixed_vector<AZStd::string, commandOptions.size()> overrideArgs;
for (auto&& [optionKey, regsetKey] : commandOptions)
{
if (size_t optionCount = commandLine.GetNumSwitchValues(optionKey); optionCount > 0)
{
// Use the last supplied command option value to override previous values
auto overrideArg = AZStd::string::format(
R"(--regset="%s=%s")", regsetKey.c_str(), commandLine.GetSwitchValue(optionKey, optionCount - 1).c_str());
overrideArgs.emplace_back(AZStd::move(overrideArg));
}
}
if (!overrideArgs.empty())
{
// Dump the input command line, add the additional option overrides
// and Parse the new command line args (write back) into the input command line.
AZ::CommandLine::ParamContainer commandLineArgs;
commandLine.Dump(commandLineArgs);
commandLineArgs.insert(
commandLineArgs.end(), AZStd::make_move_iterator(overrideArgs.begin()), AZStd::make_move_iterator(overrideArgs.end()));
commandLine.Parse(commandLineArgs);
}
}
bool DumpSettingsRegistryToStream(SettingsRegistryInterface& registry, AZStd::string_view key,
AZ::IO::GenericStream& stream, const DumperSettings& dumperSettings)
{

@ -55,6 +55,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! Development write storage path may be considered temporary or cache storage on some platforms
inline static constexpr char FilePathKey_DevWriteStorage[] = "/Amazon/AzCore/Runtime/FilePaths/DevWriteStorage";
//! Stores error text regarding engine boot sequence when engine and project roots cannot be determined
inline static constexpr char FilePathKey_ErrorText[] = "/Amazon/AzCore/Runtime/FilePaths/ErrorText";
//! 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
@ -219,6 +222,9 @@ namespace AZ::SettingsRegistryMergeUtils
//! into the AZ::CommandLine instance
bool GetCommandLineFromRegistry(SettingsRegistryInterface& registry, AZ::CommandLine& commandLine);
//! Parse a CommandLine and transform certain options into formal "regset" options
void ParseCommandLine(AZ::CommandLine& commandLine);
//! Structure for configuring how values should be dumped from the Settings Registry
struct DumperSettings
{

@ -22,7 +22,7 @@ namespace AZ
{
namespace NativeUI
{
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
{
AZ::Android::JNI::Object object("com/amazon/lumberyard/NativeUI/LumberyardNativeUI");
object.RegisterStaticMethod("DisplayDialog", "(Landroid/app/Activity;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V");

@ -12,16 +12,11 @@
#include <AzCore/NativeUI/NativeUISystemComponent.h>
namespace AZ
namespace AZ::NativeUI
{
namespace NativeUI
AZStd::string NativeUISystem::DisplayBlockingDialog([[maybe_unused]] const AZStd::string& title, [[maybe_unused]] const AZStd::string& message,
[[maybe_unused]] const AZStd::vector<AZStd::string>& options) const
{
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
{
AZ_UNUSED(title);
AZ_UNUSED(message);
AZ_UNUSED(options);
return "";
}
return {};
}
}

@ -26,7 +26,7 @@ namespace AZ
{
namespace NativeUI
{
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
{
__block NSModalResponse response = -1;

@ -245,7 +245,7 @@ namespace AZ
{
namespace NativeUI
{
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
{
if (options.size() >= MAX_ITEMS)
{

@ -18,7 +18,7 @@ namespace AZ
{
namespace NativeUI
{
AZStd::string NativeUISystemComponent::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
AZStd::string NativeUISystem::DisplayBlockingDialog(const AZStd::string& title, const AZStd::string& message, const AZStd::vector<AZStd::string>& options) const
{
__block AZStd::string userSelection = "";

@ -175,7 +175,7 @@ namespace AzFramework
}
// Initializes the IArchive for reading archive(.pak) files
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); !archive)
if (auto archive = AZ::Interface<AZ::IO::IArchive>::Get(); archive == nullptr)
{
m_archive = AZStd::make_unique<AZ::IO::Archive>();
AZ::Interface<AZ::IO::IArchive>::Register(m_archive.get());
@ -189,6 +189,12 @@ namespace AzFramework
SetFileIOAliases();
}
if (auto nativeUI = AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get(); nativeUI == nullptr)
{
m_nativeUI = AZStd::make_unique<AZ::NativeUI::NativeUISystem>();
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Register(m_nativeUI.get());
}
ApplicationRequests::Bus::Handler::BusConnect();
AZ::UserSettingsFileLocatorBus::Handler::BusConnect();
NetSystemRequestBus::Handler::BusConnect();
@ -205,12 +211,17 @@ namespace AzFramework
AZ::UserSettingsFileLocatorBus::Handler::BusDisconnect();
ApplicationRequests::Bus::Handler::BusDisconnect();
if (AZ::Interface<AZ::NativeUI::NativeUIRequests>::Get() == m_nativeUI.get())
{
AZ::Interface<AZ::NativeUI::NativeUIRequests>::Unregister(m_nativeUI.get());
}
m_nativeUI.reset();
// Unset the Archive file IO if it is set as the direct instance
if (AZ::IO::FileIOBase::GetInstance() == m_archiveFileIO.get())
{
AZ::IO::FileIOBase::SetInstance(nullptr);
}
m_archiveFileIO.reset();
// Destroy the IArchive instance
@ -303,7 +314,6 @@ namespace AzFramework
azrtti_typeid<AZ::AssetManagerComponent>(),
azrtti_typeid<AZ::UserSettingsComponent>(),
azrtti_typeid<AZ::Debug::FrameProfilerComponent>(),
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
azrtti_typeid<AZ::SliceComponent>(),
azrtti_typeid<AZ::SliceSystemComponent>(),
@ -372,7 +382,6 @@ namespace AzFramework
azrtti_typeid<AZ::UserSettingsComponent>(),
azrtti_typeid<AZ::ScriptSystemComponent>(),
azrtti_typeid<AZ::JobManagerComponent>(),
azrtti_typeid<AZ::NativeUI::NativeUISystemComponent>(),
azrtti_typeid<AZ::SliceSystemComponent>(),
azrtti_typeid<AzFramework::AssetCatalogComponent>(),

@ -16,6 +16,7 @@
#include <AzCore/Component/ComponentApplication.h>
#include <AzCore/UserSettings/UserSettings.h>
#include <AzCore/Math/Uuid.h>
#include <AzCore/NativeUI/NativeUIRequests.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/std/smart_ptr/unique_ptr.h>
#include <AzCore/std/string/fixed_string.h>
@ -187,6 +188,7 @@ namespace AzFramework
AZStd::unique_ptr<AZ::IO::FileIOBase> m_archiveFileIO; ///> The Default file IO instance is a ArchiveFileIO.
AZStd::unique_ptr<AZ::IO::Archive> m_archive; ///> The AZ::IO::Instance
AZStd::unique_ptr<Implementation> m_pimpl;
AZStd::unique_ptr<AZ::NativeUI::NativeUIRequests> m_nativeUI;
bool m_ownsConsole = false;
bool m_exitMainLoopRequested = false;

@ -220,7 +220,7 @@ namespace AzFramework
{
// Read the wait for connection boolean from the Settings Registry
AZ::s64 waitForConnect64{};
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
if (AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect64, AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, AzFramework::AssetSystem::WaitForConnect))
{
outputConnectionSettings.m_waitForConnect = waitForConnect64 != 0;
}

@ -41,9 +41,10 @@ namespace AzFramework::ProjectManager
// at the end of the function
AZ::CommandLine commandLine;
commandLine.Parse(argc, argv);
AZ::SettingsRegistryImpl settingsRegistry;
// Store the Command line to the Setting Registry
AZ::SettingsRegistryMergeUtils::ParseCommandLine(commandLine);
// Store the Command line to the Setting Registry
AZ::SettingsRegistryImpl settingsRegistry;
AZ::SettingsRegistryMergeUtils::StoreCommandLineToRegistry(settingsRegistry, commandLine);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});
@ -68,7 +69,14 @@ namespace AzFramework::ProjectManager
// If we were able to locate a path to a project, we're done
if (!projectRootPath.empty())
{
return ProjectPathCheckResult::ProjectPathFound;
AZ::IO::FixedMaxPath projectJsonPath = engineRootPath / projectRootPath / "project.json";
if (AZ::IO::SystemFile::Exists(projectJsonPath.c_str()))
{
return ProjectPathCheckResult::ProjectPathFound;
}
AZ_TracePrintf(
"ProjectManager", "Did not find a project file at location '%s', launching the Project Manager...",
projectJsonPath.c_str());
}
if (LaunchProjectManager(engineRootPath))

@ -284,6 +284,10 @@ namespace AzToolsFramework
void ToolsApplication::Start(const Descriptor& descriptor, const StartupParameters& startupParameters/* = StartupParameters()*/)
{
Application::Start(descriptor, startupParameters);
if (!m_isStarted)
{
return;
}
m_editorEntityManager.Start();

@ -5045,12 +5045,28 @@ extern "C"
#pragma comment(lib, "Shell32.lib")
#endif
struct CryAllocatorsRAII
{
CryAllocatorsRAII()
{
AZ_Assert(!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ_Assert(!AZ::AllocatorInstance<CryStringAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
AZ::AllocatorInstance<CryStringAllocator>::Create();
}
~CryAllocatorsRAII()
{
AZ::AllocatorInstance<CryStringAllocator>::Destroy();
AZ::AllocatorInstance<AZ::LegacyAllocator>::Destroy();
}
};
extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
{
AZ_Assert(!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
AZ_Assert(!AZ::AllocatorInstance<CryStringAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ::AllocatorInstance<CryStringAllocator>::Create();
CryAllocatorsRAII cryAllocatorsRAII;
// ensure the EditorEventsBus context gets created inside EditorLib
[[maybe_unused]] const auto& editorEventsContext = AzToolsFramework::EditorEvents::Bus::GetOrCreateContext();
@ -5058,7 +5074,7 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
// connect relevant buses to global settings
gSettings.Connect();
CCryEditApp* theApp = new CCryEditApp();
auto theApp = AZStd::make_unique<CCryEditApp>();
// this does some magic to set the current directory...
{
QCoreApplication app(argc, argv);
@ -5145,8 +5161,6 @@ extern "C" int AZ_DLL_EXPORT CryEditMain(int argc, char* argv[])
}
delete theApp;
gSettings.Disconnect();
return ret;

@ -30,17 +30,14 @@ int main(int argc, char* argv[])
[[maybe_unused]] const bool loaded = handle->Load(true);
AZ_Assert(loaded, "EditorLib could not be loaded");
int ret = 1;
if (auto fn = handle->GetFunction<CryEditMain>(CryEditMainName); fn != nullptr)
{
const int ret = AZStd::invoke(fn, argc, argv);
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
AZ::Environment::Detach();
return ret;
ret = AZStd::invoke(fn, argc, argv);
}
handle = {};
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
AZ::Environment::Detach();
return 1;
return ret;
}

@ -579,6 +579,8 @@ int rcmain(int argc, char** argv, [[maybe_unused]] char** envp)
// on the command line
AZ::CommandLine commandLine;
commandLine.Parse(argc, argv);
AZ::SettingsRegistryMergeUtils::ParseCommandLine(commandLine);
AZ::SettingsRegistryImpl settingsRegistry;
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_Bootstrap(settingsRegistry);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_O3deUserRegistry(settingsRegistry, AZ_TRAIT_OS_PLATFORM_CODENAME, {});

Loading…
Cancel
Save