Browse Source

Added the ability initialize the Settings Registry with a JSON string via the ComponentApplication (#16873)

* Added constructor to ComponentApplication derived classes to accept a
Settings structure.

The Settings structure can be used to bootstrap the Settings Registry
with an initial JSON string.

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Updated the Launcher to init the Settings Registry with JSON string

Instead of injecting command line parameters to initialize the Settings
Registry project name and project path settings, the Launcher now
supplies a JSON string which will initialize the project name and
project path settings only once.

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Added an early return for MergeSettingsString

If the supplied string is empty, there is no merging to be done, so so
need to pass that string to Rapidjson

Signed-off-by: lumberyard-employee-dm <[email protected]>

* Removed unused projectPathOverride/enginePathOverride variables.

Signed-off-by: lumberyard-employee-dm <[email protected]>

---------

Signed-off-by: lumberyard-employee-dm <[email protected]>
lumberyard-employee-dm 1 year ago
parent
commit
1b9ba75d13
31 changed files with 249 additions and 55 deletions
  1. 10 1
      Code/Editor/EditorToolsApplication.cpp
  2. 3 1
      Code/Editor/EditorToolsApplication.h
  3. 14 3
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
  4. 18 1
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
  5. 13 3
      Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp
  6. 13 2
      Code/Framework/AzFramework/AzFramework/Application/Application.cpp
  7. 4 0
      Code/Framework/AzFramework/AzFramework/Application/Application.h
  8. 12 1
      Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp
  9. 4 0
      Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.h
  10. 1 1
      Code/Framework/AzQtComponents/AzQtComponents/PropertyEditorStandalone/main.cpp
  11. 9 1
      Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp
  12. 2 0
      Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h
  13. 10 2
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp
  14. 2 0
      Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h
  15. 24 23
      Code/LauncherUnified/Launcher.cpp
  16. 10 1
      Code/Tools/AssetBundler/source/utils/applicationManager.cpp
  17. 3 1
      Code/Tools/AssetBundler/source/utils/applicationManager.h
  18. 6 1
      Code/Tools/AssetProcessor/AssetBuilder/AssetBuilderApplication.cpp
  19. 1 0
      Code/Tools/AssetProcessor/AssetBuilder/AssetBuilderApplication.h
  20. 22 3
      Code/Tools/AssetProcessor/native/utilities/ApplicationManager.cpp
  21. 6 2
      Code/Tools/AssetProcessor/native/utilities/ApplicationManager.h
  22. 12 1
      Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp
  23. 3 1
      Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.h
  24. 11 1
      Code/Tools/AssetProcessor/native/utilities/BatchApplicationManager.cpp
  25. 3 1
      Code/Tools/AssetProcessor/native/utilities/BatchApplicationManager.h
  26. 11 1
      Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.cpp
  27. 3 1
      Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.h
  28. 10 1
      Code/Tools/SerializeContextTools/Application.cpp
  29. 2 0
      Code/Tools/SerializeContextTools/Application.h
  30. 1 0
      Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h
  31. 6 1
      Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp

+ 10 - 1
Code/Editor/EditorToolsApplication.cpp

@@ -31,8 +31,17 @@
 
 
 namespace EditorInternal
 namespace EditorInternal
 {
 {
+    EditorToolsApplication::EditorToolsApplication(AZ::ComponentApplicationSettings componentAppSettings)
+        : EditorToolsApplication(nullptr, nullptr, AZStd::move(componentAppSettings))
+    {
+    }
     EditorToolsApplication::EditorToolsApplication(int* argc, char*** argv)
     EditorToolsApplication::EditorToolsApplication(int* argc, char*** argv)
-        : ToolsApplication(argc, argv)
+        : EditorToolsApplication(argc, argv, {})
+    {
+    }
+
+    EditorToolsApplication::EditorToolsApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+        : ToolsApplication(argc, argv, AZStd::move(componentAppSettings))
     {
     {
         EditorToolsApplicationRequests::Bus::Handler::BusConnect();
         EditorToolsApplicationRequests::Bus::Handler::BusConnect();
         AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect();
         AzToolsFramework::ViewportInteraction::EditorModifierKeyRequestBus::Handler::BusConnect();

+ 3 - 1
Code/Editor/EditorToolsApplication.h

@@ -25,8 +25,10 @@ namespace EditorInternal
         , public AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Handler
         , public AzToolsFramework::ViewportInteraction::EditorViewportInputTimeNowRequestBus::Handler
     {
     {
     public:
     public:
-        AZ_CLASS_ALLOCATOR(EditorToolsApplication, AZ::SystemAllocator)
+        AZ_CLASS_ALLOCATOR(EditorToolsApplication, AZ::SystemAllocator);
         EditorToolsApplication(int* argc, char*** argv);
         EditorToolsApplication(int* argc, char*** argv);
+        explicit EditorToolsApplication(AZ::ComponentApplicationSettings componentAppSettings);
+        EditorToolsApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
         ~EditorToolsApplication();
         ~EditorToolsApplication();
 
 
         bool IsStartupAborted() const;
         bool IsStartupAborted() const;

+ 14 - 3
Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp

@@ -416,11 +416,20 @@ namespace AZ
     // [5/30/2012]
     // [5/30/2012]
     //=========================================================================
     //=========================================================================
     ComponentApplication::ComponentApplication()
     ComponentApplication::ComponentApplication()
-        : ComponentApplication(0, nullptr)
+        : ComponentApplication(0, nullptr, {})
     {
     {
     }
     }
 
 
+    ComponentApplication::ComponentApplication(ComponentApplicationSettings componentAppSettings)
+        : ComponentApplication(0, nullptr, AZStd::move(componentAppSettings))
+    {
+    }
     ComponentApplication::ComponentApplication(int argC, char** argV)
     ComponentApplication::ComponentApplication(int argC, char** argV)
+        : ComponentApplication(argC, argV, {})
+    {
+    }
+
+    ComponentApplication::ComponentApplication(int argC, char** argV, ComponentApplicationSettings componentAppSettings)
         : m_timeSystem(AZStd::make_unique<TimeSystem>())
         : m_timeSystem(AZStd::make_unique<TimeSystem>())
     {
     {
         if (Interface<ComponentApplicationRequests>::Get() == nullptr)
         if (Interface<ComponentApplicationRequests>::Get() == nullptr)
@@ -463,7 +472,7 @@ namespace AZ
             m_nameDictionary->LoadDeferredNames(AZ::Name::GetDeferredHead());
             m_nameDictionary->LoadDeferredNames(AZ::Name::GetDeferredHead());
         }
         }
 
 
-        InitializeSettingsRegistry();
+        InitializeSettingsRegistry(componentAppSettings);
 
 
         InitializeEventLoggerFactory();
         InitializeEventLoggerFactory();
 
 
@@ -550,7 +559,7 @@ namespace AZ
         AZ::Debug::Trace::Instance().Destroy();
         AZ::Debug::Trace::Instance().Destroy();
     }
     }
 
 
-    void ComponentApplication::InitializeSettingsRegistry()
+    void ComponentApplication::InitializeSettingsRegistry(const ComponentApplicationSettings& componentAppSettings)
     {
     {
         SettingsRegistryMergeUtils::ParseCommandLine(m_commandLine);
         SettingsRegistryMergeUtils::ParseCommandLine(m_commandLine);
 
 
@@ -558,6 +567,8 @@ namespace AZ
         // This is done after the AppRoot has been calculated so that the Bootstrap.cfg
         // This is done after the AppRoot has been calculated so that the Bootstrap.cfg
         // can be read to determine the Game folder and the asset platform
         // can be read to determine the Game folder and the asset platform
         m_settingsRegistry = AZStd::make_unique<SettingsRegistryImpl>();
         m_settingsRegistry = AZStd::make_unique<SettingsRegistryImpl>();
+        // Merge the bootstrap settings to the root of the Settings Registry
+        m_settingsRegistry->MergeSettings(componentAppSettings.m_setregBootstrapJson, componentAppSettings.m_setregFormat);
 
 
         // Register the Settings Registry with the AZ Interface if there isn't one registered already
         // Register the Settings Registry with the AZ Interface if there isn't one registered already
         if (SettingsRegistry::Get() == nullptr)
         if (SettingsRegistry::Get() == nullptr)

+ 18 - 1
Code/Framework/AzCore/AzCore/Component/ComponentApplication.h

@@ -71,6 +71,17 @@ namespace AZ
 
 
     };
     };
 
 
+    //! Settings used to customize the constructor calls for the ComponentApplications
+    //! This differs from the ComponentApplication::StartupParameters and ComponentApplication::Descriptor structs
+    //! These settings are only used at construction time of the ComponentApplication and not in ComponentApplication::Create()
+    struct ComponentApplicationSettings
+    {
+        //! JSON string that will be merged to the Settings Registry right after construction
+        AZStd::string_view m_setregBootstrapJson;
+        //! Defaults to merging the JSON string using JSON Merge Patch, where a regular JSON string can be supplied
+        AZ::SettingsRegistryInterface::Format m_setregFormat = AZ::SettingsRegistryInterface::Format::JsonMergePatch;
+    };
+
     /**
     /**
      * A main class that can be used directly or as a base to start a
      * A main class that can be used directly or as a base to start a
      * component based application. It will provide all the proper bootstrap
      * component based application. It will provide all the proper bootstrap
@@ -151,6 +162,10 @@ namespace AZ
 
 
         ComponentApplication();
         ComponentApplication();
         ComponentApplication(int argC, char** argV);
         ComponentApplication(int argC, char** argV);
+        // Allows passing in a JSON Merge Patch string that can bootstrap
+        // the settings registry with an initial set of settings
+        explicit ComponentApplication(ComponentApplicationSettings componentAppSettings);
+        ComponentApplication(int argC, char** argV, ComponentApplicationSettings componentAppSettings);
         virtual ~ComponentApplication();
         virtual ~ComponentApplication();
 
 
         /**
         /**
@@ -272,7 +287,9 @@ namespace AZ
         void LoadDynamicModules();
         void LoadDynamicModules();
 
 
     protected:
     protected:
-        void InitializeSettingsRegistry();
+        //! The Bootstrap JSON settings are merged to the Settings Registry immediately
+        //! after creation
+        void InitializeSettingsRegistry(const ComponentApplicationSettings& componentAppSettings);
         void InitializeEventLoggerFactory();
         void InitializeEventLoggerFactory();
         void InitializeLifecyleEvents(SettingsRegistryInterface& settingsRegistry);
         void InitializeLifecyleEvents(SettingsRegistryInterface& settingsRegistry);
         void InitializeConsole(SettingsRegistryInterface& settingsRegistry);
         void InitializeConsole(SettingsRegistryInterface& settingsRegistry);

+ 13 - 3
Code/Framework/AzCore/AzCore/Settings/SettingsRegistryImpl.cpp

@@ -1264,6 +1264,15 @@ namespace AZ
         AZ::IO::PathView filePath)
         AZ::IO::PathView filePath)
         -> MergeSettingsResult
         -> MergeSettingsResult
     {
     {
+        // There is no work to be done for an empty JSON string
+        if (jsonData.empty())
+        {
+            MergeSettingsResult mergeResult;
+            mergeResult.m_returnCode = MergeSettingsReturnCode::Failure;
+            mergeResult.m_operationMessages = "JSON String is empty. No merging to be done";
+            return mergeResult;
+        }
+
         rapidjson::Document jsonPatch;
         rapidjson::Document jsonPatch;
         constexpr int flags = rapidjson::kParseStopWhenDoneFlag | rapidjson::kParseCommentsFlag | rapidjson::kParseTrailingCommasFlag;
         constexpr int flags = rapidjson::kParseStopWhenDoneFlag | rapidjson::kParseCommentsFlag | rapidjson::kParseTrailingCommasFlag;
         jsonPatch.ParseInsitu<flags>(jsonData.data());
         jsonPatch.ParseInsitu<flags>(jsonData.data());
@@ -1272,9 +1281,10 @@ namespace AZ
             MergeSettingsResult mergeResult;
             MergeSettingsResult mergeResult;
             mergeResult.m_returnCode = MergeSettingsReturnCode::Failure;
             mergeResult.m_returnCode = MergeSettingsReturnCode::Failure;
             mergeResult.m_operationMessages = "Unable to parse ";
             mergeResult.m_operationMessages = "Unable to parse ";
-            mergeResult.m_operationMessages += filePath.empty() ? "data"
-                : AZStd::string::format(R"(registry file "%.*s")", AZ_PATH_ARG(filePath));
-            mergeResult.m_operationMessages += " at offset %zu.";
+            mergeResult.m_operationMessages +=
+                filePath.empty() ? "data" : AZStd::string::format(R"(registry file "%.*s")", AZ_PATH_ARG(filePath));
+            mergeResult.m_operationMessages += AZStd::string::format(
+                " at offset %zu.\nError: %s", jsonPatch.GetErrorOffset(), rapidjson::GetParseError_En(jsonPatch.GetParseError()));
             return mergeResult;
             return mergeResult;
         }
         }
 
 

+ 13 - 2
Code/Framework/AzFramework/AzFramework/Application/Application.cpp

@@ -100,14 +100,25 @@ namespace AzFramework
     }
     }
 
 
     Application::Application()
     Application::Application()
-        : Application(nullptr, nullptr)
+        : Application(nullptr, nullptr, {})
+    {
+    }
+
+    Application::Application(AZ::ComponentApplicationSettings componentAppSettings)
+        : Application(nullptr, nullptr, AZStd::move(componentAppSettings))
     {
     {
     }
     }
 
 
     Application::Application(int* argc, char*** argv)
     Application::Application(int* argc, char*** argv)
+        : Application(argc, argv, {})
+    {
+    }
+
+    Application::Application(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
         : ComponentApplication(
         : ComponentApplication(
             argc ? *argc : 0,
             argc ? *argc : 0,
-            argv ? *argv : nullptr
+            argv ? *argv : nullptr,
+            AZStd::move(componentAppSettings)
         )
         )
     {
     {
         // Startup default local FileIO (hits OSAllocator) if not already setup.
         // Startup default local FileIO (hits OSAllocator) if not already setup.

+ 4 - 0
Code/Framework/AzFramework/AzFramework/Application/Application.h

@@ -81,6 +81,10 @@ namespace AzFramework
          */
          */
         Application(int* argc, char*** argv);  ///< recommended:  supply &argc and &argv from void main(...) here.
         Application(int* argc, char*** argv);  ///< recommended:  supply &argc and &argv from void main(...) here.
         Application(); ///< for backward compatibility.  If you call this, GetArgC and GetArgV will return nullptr.
         Application(); ///< for backward compatibility.  If you call this, GetArgC and GetArgV will return nullptr.
+        // Allows passing in a JSON Merge Patch string that can bootstrap
+        // the settings registry with an initial set of settings
+        explicit Application(AZ::ComponentApplicationSettings componentAppSettings);
+        Application(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
         ~Application();
         ~Application();
 
 
         /**
         /**

+ 12 - 1
Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.cpp

@@ -22,11 +22,22 @@
 namespace AzGameFramework
 namespace AzGameFramework
 {
 {
     GameApplication::GameApplication()
     GameApplication::GameApplication()
+        : GameApplication(0, nullptr, {})
+    {
+    }
+
+    GameApplication::GameApplication(AZ::ComponentApplicationSettings componentAppSettings)
+        : GameApplication(0, nullptr, AZStd::move(componentAppSettings))
     {
     {
     }
     }
 
 
     GameApplication::GameApplication(int argc, char** argv)
     GameApplication::GameApplication(int argc, char** argv)
-        : Application(&argc, &argv)
+        : GameApplication(argc, argv, {})
+    {
+    }
+
+    GameApplication::GameApplication(int argc, char** argv, AZ::ComponentApplicationSettings componentAppSettings)
+        : Application(&argc, &argv, AZStd::move(componentAppSettings))
     {
     {
         // In the Launcher Applications the Settings Registry
         // In the Launcher Applications the Settings Registry
         // can read from the FileIOBase instance if available
         // can read from the FileIOBase instance if available

+ 4 - 0
Code/Framework/AzGameFramework/AzGameFramework/Application/GameApplication.h

@@ -21,6 +21,10 @@ namespace AzGameFramework
 
 
         GameApplication();
         GameApplication();
         GameApplication(int argc, char** argvS);
         GameApplication(int argc, char** argvS);
+        // Allows passing in a JSON Merge Patch string that can bootstrap
+        // the settings registry with an initial set of settings
+        explicit GameApplication(AZ::ComponentApplicationSettings componentAppSettings);
+        GameApplication(int argc, char** argvS, AZ::ComponentApplicationSettings componentAppSettings);
         ~GameApplication();
         ~GameApplication();
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////

+ 1 - 1
Code/Framework/AzQtComponents/AzQtComponents/PropertyEditorStandalone/main.cpp

@@ -153,7 +153,7 @@ namespace StandaloneRPE
 class RPEApplication : public AzToolsFramework::ToolsApplication
 class RPEApplication : public AzToolsFramework::ToolsApplication
 {
 {
 public:
 public:
-    RPEApplication(int* argc = nullptr, char*** argv = nullptr) : AzToolsFramework::ToolsApplication(argc, argv) {}
+    using AzToolsFramework::ToolsApplication::ToolsApplication;
 
 
     void Reflect(AZ::ReflectContext* context) override
     void Reflect(AZ::ReflectContext* context) override
     {
     {

+ 9 - 1
Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.cpp

@@ -248,8 +248,16 @@ namespace AzToolsFramework
 
 
     } // Internal
     } // Internal
 
 
+    ToolsApplication::ToolsApplication(AZ::ComponentApplicationSettings componentAppSettings)
+        : ToolsApplication(nullptr, nullptr, AZStd::move(componentAppSettings))
+    {
+    }
     ToolsApplication::ToolsApplication(int* argc, char*** argv)
     ToolsApplication::ToolsApplication(int* argc, char*** argv)
-        : AzFramework::Application(argc, argv)
+        : ToolsApplication(argc, argv, {})
+    {
+    }
+    ToolsApplication::ToolsApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+        : AzFramework::Application(argc, argv, AZStd::move(componentAppSettings))
         , m_selectionBounds(AZ::Aabb())
         , m_selectionBounds(AZ::Aabb())
         , m_undoStack(nullptr)
         , m_undoStack(nullptr)
         , m_currentBatchUndo(nullptr)
         , m_currentBatchUndo(nullptr)

+ 2 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/Application/ToolsApplication.h

@@ -37,6 +37,8 @@ namespace AzToolsFramework
         AZ_CLASS_ALLOCATOR(ToolsApplication, AZ::SystemAllocator);
         AZ_CLASS_ALLOCATOR(ToolsApplication, AZ::SystemAllocator);
 
 
         ToolsApplication(int* argc = nullptr, char*** argv = nullptr);
         ToolsApplication(int* argc = nullptr, char*** argv = nullptr);
+        explicit ToolsApplication(AZ::ComponentApplicationSettings componentAppSettings);
+        ToolsApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
         ~ToolsApplication();
         ~ToolsApplication();
 
 
         void Stop() override;
         void Stop() override;

+ 10 - 2
Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.cpp

@@ -93,10 +93,18 @@ namespace LegacyFramework
     }
     }
 
 
     Application::Application()
     Application::Application()
-        : Application(0, nullptr)
+        : Application(0, nullptr, {})
     {}
     {}
+
+    Application::Application(AZ::ComponentApplicationSettings componentAppSettings)
+        : Application(0, nullptr, AZStd::move(componentAppSettings))
+    {}
+
     Application::Application(int argc, char** argv)
     Application::Application(int argc, char** argv)
-        : ComponentApplication(argc, argv)
+        : Application(argc, argv, {})
+    {}
+    Application::Application(int argc, char** argv, AZ::ComponentApplicationSettings componentAppSettings)
+        : ComponentApplication(argc, argv, AZStd::move(componentAppSettings))
     {
     {
         m_isPrimary = true;
         m_isPrimary = true;
         m_desiredExitCode = 0;
         m_desiredExitCode = 0;

+ 2 - 0
Code/Framework/AzToolsFramework/AzToolsFramework/UI/LegacyFramework/Core/EditorFrameworkApplication.h

@@ -57,6 +57,8 @@ namespace LegacyFramework
         virtual int Run(const ApplicationDesc& desc);
         virtual int Run(const ApplicationDesc& desc);
         Application();
         Application();
         Application(int argc, char** argv);
         Application(int argc, char** argv);
+        explicit Application(AZ::ComponentApplicationSettings componentAppSettings);
+        Application(int argc, char** argv, AZ::ComponentApplicationSettings componentAppSettings);
 
 
         void CreateReflectionManager() override;
         void CreateReflectionManager() override;
 
 

+ 24 - 23
Code/LauncherUnified/Launcher.cpp

@@ -354,28 +354,26 @@ namespace O3DELauncher
         ArgumentContainer argContainer(gameArgV, gameArgV + gameArgC);
         ArgumentContainer argContainer(gameArgV, gameArgV + gameArgC);
 
 
         using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
         using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString;
-        // Inject the Engine Path, Project Path and Project Name into the CommandLine parameters to the command line
-        // in order to be used in the Settings Registry
 
 
-        // The command line overrides are stored in the following fixed strings
-        // until the ComponentApplication constructor can parse the command line parameters
-        FixedValueString projectNameOptionOverride;
+        // Initialize the Settings Registry with the Engine Path, Project Path and Project Name settings
+        // Add the initial JSON object for "/O3DE/Runtime/Manifest/Project" and "/Amazon/AzCore/Bootstrap"
+        FixedValueString launcherJsonPatch = R"(
+            [
+                { "op": "add", "path": "/O3DE", "value": { "Runtime": { "Manifest": { "Project": {} } } } },
+                { "op": "add", "path": "/Amazon", "value": { "AzCore": { "Bootstrap": {} } } })";
 
 
-        // Insert the project_name option to the front
+        // Query the project_name baked into the launcher executable
         const AZStd::string_view launcherProjectName = GetProjectName();
         const AZStd::string_view launcherProjectName = GetProjectName();
         if (!launcherProjectName.empty())
         if (!launcherProjectName.empty())
         {
         {
-            const auto projectNameKey = FixedValueString(AZ::SettingsRegistryMergeUtils::ProjectSettingsRootKey) + "/project_name";
-            projectNameOptionOverride = FixedValueString::format(R"(--regset="%s=%.*s")",
-                projectNameKey.c_str(), aznumeric_cast<int>(launcherProjectName.size()), launcherProjectName.data());
-            argContainer.emplace_back(projectNameOptionOverride.data());
+            // Append the project name setting to the JSON Patch
+            launcherJsonPatch += FixedValueString::format(R"(,
+                { "op": "add", "path": "/O3DE/Runtime/Manifest/Project/project_name", "value": "%.*s" })", AZ_STRING_ARG(launcherProjectName));
         }
         }
 
 
         // Non-host platforms cannot use the project path that is #defined within the launcher.
         // Non-host platforms cannot use the project path that is #defined within the launcher.
         // In this case the the result of AZ::Utils::GetDefaultAppRoot is used instead
         // In this case the the result of AZ::Utils::GetDefaultAppRoot is used instead
 #if !AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
 #if !AZ_TRAIT_OS_IS_HOST_OS_PLATFORM
-        FixedValueString projectPathOptionOverride;
-        FixedValueString enginePathOptionOverride;
         AZStd::string_view projectPath;
         AZStd::string_view projectPath;
         // Make sure the defaultAppRootPath variable is in scope long enough until the projectPath string_view is used below
         // Make sure the defaultAppRootPath variable is in scope long enough until the projectPath string_view is used below
         AZStd::optional<AZ::IO::FixedMaxPathString> defaultAppRootPath = AZ::Utils::GetDefaultAppRootPath();
         AZStd::optional<AZ::IO::FixedMaxPathString> defaultAppRootPath = AZ::Utils::GetDefaultAppRootPath();
@@ -385,24 +383,27 @@ namespace O3DELauncher
         }
         }
         if (!projectPath.empty())
         if (!projectPath.empty())
         {
         {
-            const auto projectPathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
-                + "/project_path";
-            projectPathOptionOverride = FixedValueString::format(R"(--regset="%s=%.*s")",
-                projectPathKey.c_str(), aznumeric_cast<int>(projectPath.size()), projectPath.data());
-            argContainer.emplace_back(projectPathOptionOverride.data());
+            launcherJsonPatch += FixedValueString::format(R"(,
+                { "op": "add", "path": "/Amazon/AzCore/Bootstrap/project_path", "value": "%.*s" })", AZ_STRING_ARG(projectPath));
+
 
 
             // For non-host platforms set the engine root to be the project root
             // For non-host platforms set the engine root to be the project root
             // Since the directories available during execution are limited on those platforms
             // Since the directories available during execution are limited on those platforms
             AZStd::string_view enginePath = projectPath;
             AZStd::string_view enginePath = projectPath;
-            const auto enginePathKey = FixedValueString(AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey)
-                + "/engine_path";
-            enginePathOptionOverride = FixedValueString ::format(R"(--regset="%s=%.*s")",
-                enginePathKey.c_str(), aznumeric_cast<int>(enginePath.size()), enginePath.data());
-            argContainer.emplace_back(enginePathOptionOverride.data());
+            launcherJsonPatch += FixedValueString::format(R"(,
+                { "op": "add", "path": "/Amazon/AzCore/Bootstrap/engine_path", "value": "%.*s" })", AZ_STRING_ARG(enginePath));
         }
         }
 #endif
 #endif
 
 
-        AzGameFramework::GameApplication gameApplication(aznumeric_cast<int>(argContainer.size()), argContainer.data());
+        // Now terminate the JSON Patch array with a trailing ']'
+        launcherJsonPatch += R"(
+            ])";
+
+        AZ::ComponentApplicationSettings componentAppSettings;
+        componentAppSettings.m_setregBootstrapJson = launcherJsonPatch;
+        // Treat the bootstrap JSON as being in JSON Patch format
+        componentAppSettings.m_setregFormat = AZ::SettingsRegistryInterface::Format::JsonPatch;
+        AzGameFramework::GameApplication gameApplication(aznumeric_cast<int>(argContainer.size()), argContainer.data(), AZStd::move(componentAppSettings));
         // The settings registry has been created by the AZ::ComponentApplication constructor at this point
         // The settings registry has been created by the AZ::ComponentApplication constructor at this point
         auto settingsRegistry = AZ::SettingsRegistry::Get();
         auto settingsRegistry = AZ::SettingsRegistry::Get();
         if (settingsRegistry == nullptr)
         if (settingsRegistry == nullptr)

+ 10 - 1
Code/Tools/AssetBundler/source/utils/applicationManager.cpp

@@ -40,8 +40,17 @@ namespace AssetBundler
     const char compareVariablePrefix = '$';
     const char compareVariablePrefix = '$';
 
 
     ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent)
     ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent)
+        : ApplicationManager(argc, argv, parent, {})
+    {
+    }
+    ApplicationManager::ApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+        : ApplicationManager(argc, argv, nullptr, AZStd::move(componentAppSettings))
+    {
+    }
+
+    ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
         : QObject(parent)
         : QObject(parent)
-        , AzToolsFramework::ToolsApplication(argc, argv)
+        , AzToolsFramework::ToolsApplication(argc, argv, AZStd::move(componentAppSettings))
     {
     {
     }
     }
 
 

+ 3 - 1
Code/Tools/AssetBundler/source/utils/applicationManager.h

@@ -165,7 +165,9 @@ namespace AssetBundler
         Q_OBJECT
         Q_OBJECT
     public:
     public:
         AZ_CLASS_ALLOCATOR(ApplicationManager, AZ::SystemAllocator)
         AZ_CLASS_ALLOCATOR(ApplicationManager, AZ::SystemAllocator)
-        explicit ApplicationManager(int* argc, char*** argv, QObject* parent = 0);
+        ApplicationManager(int* argc, char*** argv, QObject* parent = nullptr);
+        ApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
+        ApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
         virtual ~ApplicationManager();
         virtual ~ApplicationManager();
 
 
         virtual bool Init();
         virtual bool Init();

+ 6 - 1
Code/Tools/AssetProcessor/AssetBuilder/AssetBuilderApplication.cpp

@@ -93,7 +93,12 @@ AZ::ComponentTypeList AssetBuilderApplication::GetRequiredSystemComponents() con
 }
 }
 
 
 AssetBuilderApplication::AssetBuilderApplication(int* argc, char*** argv)
 AssetBuilderApplication::AssetBuilderApplication(int* argc, char*** argv)
-    : AzToolsFramework::ToolsApplication(argc, argv)
+    : AssetBuilderApplication(argc, argv, {})
+{
+}
+
+AssetBuilderApplication::AssetBuilderApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : AzToolsFramework::ToolsApplication(argc, argv, AZStd::move(componentAppSettings))
     , m_qtApplication(*argc, *argv)
     , m_qtApplication(*argc, *argv)
 {
 {
     // The settings registry has been created at this point
     // The settings registry has been created at this point

+ 1 - 0
Code/Tools/AssetProcessor/AssetBuilder/AssetBuilderApplication.h

@@ -34,6 +34,7 @@ class AssetBuilderApplication
 public:
 public:
     AZ_CLASS_ALLOCATOR(AssetBuilderApplication, AZ::SystemAllocator)
     AZ_CLASS_ALLOCATOR(AssetBuilderApplication, AZ::SystemAllocator)
     AssetBuilderApplication(int* argc, char*** argv);
     AssetBuilderApplication(int* argc, char*** argv);
+    AssetBuilderApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
     ~AssetBuilderApplication();
     ~AssetBuilderApplication();
 
 
     AZ::ComponentTypeList GetRequiredSystemComponents() const override;
     AZ::ComponentTypeList GetRequiredSystemComponents() const override;

+ 22 - 3
Code/Tools/AssetProcessor/native/utilities/ApplicationManager.cpp

@@ -112,10 +112,19 @@ namespace AssetProcessorBuildTarget
     AZStd::string_view GetBuildTargetName();
     AZStd::string_view GetBuildTargetName();
 }
 }
 
 
-
 AssetProcessorAZApplication::AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent)
 AssetProcessorAZApplication::AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent)
+    : AssetProcessorAZApplication(argc, argv, parent, {})
+{
+}
+
+AssetProcessorAZApplication::AssetProcessorAZApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : AssetProcessorAZApplication(argc, argv, nullptr, AZStd::move(componentAppSettings))
+{
+}
+
+AssetProcessorAZApplication::AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
     : QObject(parent)
     : QObject(parent)
-    , AzToolsFramework::ToolsApplication(argc, argv)
+    , AzToolsFramework::ToolsApplication(argc, argv, AZStd::move(componentAppSettings))
 {
 {
     // The settings registry has been created at this point, so add the CMake target
     // The settings registry has been created at this point, so add the CMake target
     // specialization to the settings
     // specialization to the settings
@@ -187,8 +196,18 @@ void AssetProcessorAZApplication::SetSettingsRegistrySpecializations(AZ::Setting
 }
 }
 
 
 ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent)
 ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent)
+    : ApplicationManager(argc, argv, parent, {})
+{
+}
+
+ApplicationManager::ApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : ApplicationManager(argc, argv, nullptr, AZStd::move(componentAppSettings))
+{
+}
+
+ApplicationManager::ApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
     : QObject(parent)
     : QObject(parent)
-    , m_frameworkApp(argc, argv)
+    , m_frameworkApp(argc, argv, AZStd::move(componentAppSettings))
 {
 {
     qInstallMessageHandler(&AssetProcessor::MessageHandler);
     qInstallMessageHandler(&AssetProcessor::MessageHandler);
 }
 }

+ 6 - 2
Code/Tools/AssetProcessor/native/utilities/ApplicationManager.h

@@ -40,7 +40,9 @@ class AssetProcessorAZApplication
     Q_OBJECT
     Q_OBJECT
 public:
 public:
     AZ_CLASS_ALLOCATOR(AssetProcessorAZApplication, AZ::SystemAllocator)
     AZ_CLASS_ALLOCATOR(AssetProcessorAZApplication, AZ::SystemAllocator)
-    explicit AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent = nullptr);
+    AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent = nullptr);
+    AssetProcessorAZApplication(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
+    AssetProcessorAZApplication(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
 
 
     ~AssetProcessorAZApplication() override = default;
     ~AssetProcessorAZApplication() override = default;
     /////////////////////////////////////////////////////////
     /////////////////////////////////////////////////////////
@@ -85,7 +87,9 @@ public:
         Status_Restarting,
         Status_Restarting,
         Status_Failure,
         Status_Failure,
     };
     };
-    explicit ApplicationManager(int* argc, char*** argv, QObject* parent = 0);
+    ApplicationManager(int* argc, char*** argv, QObject* parent = nullptr);
+    ApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
+    ApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
     virtual ~ApplicationManager();
     virtual ~ApplicationManager();
     //! Prepares all the prerequisite needed for the main application functionality
     //! Prepares all the prerequisite needed for the main application functionality
     //! For eg Starts the AZ Framework,Activates logging ,Initialize Qt etc
     //! For eg Starts the AZ Framework,Activates logging ,Initialize Qt etc

+ 12 - 1
Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.cpp

@@ -49,8 +49,19 @@ static const qint64 s_ReservedDiskSpaceInBytes = 256 * 1024;
 //! Maximum number of temp folders allowed
 //! Maximum number of temp folders allowed
 static const int s_MaximumTempFolders = 10000;
 static const int s_MaximumTempFolders = 10000;
 
 
+
 ApplicationManagerBase::ApplicationManagerBase(int* argc, char*** argv, QObject* parent)
 ApplicationManagerBase::ApplicationManagerBase(int* argc, char*** argv, QObject* parent)
-    : ApplicationManager(argc, argv, parent)
+    : ApplicationManagerBase(argc, argv, parent, {})
+{
+}
+
+ApplicationManagerBase::ApplicationManagerBase(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : ApplicationManagerBase(argc, argv, nullptr, AZStd::move(componentAppSettings))
+{
+}
+
+ApplicationManagerBase::ApplicationManagerBase(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
+    : ApplicationManager(argc, argv, parent, AZStd::move(componentAppSettings))
 {
 {
     qRegisterMetaType<AZ::u32>("AZ::u32");
     qRegisterMetaType<AZ::u32>("AZ::u32");
     qRegisterMetaType<AZ::Uuid>("AZ::Uuid");
     qRegisterMetaType<AZ::Uuid>("AZ::Uuid");

+ 3 - 1
Code/Tools/AssetProcessor/native/utilities/ApplicationManagerBase.h

@@ -64,7 +64,9 @@ class ApplicationManagerBase
 {
 {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit ApplicationManagerBase(int* argc, char*** argv, QObject* parent = 0);
+    ApplicationManagerBase(int* argc, char*** argv, QObject* parent = nullptr);
+    ApplicationManagerBase(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
+    ApplicationManagerBase(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
     virtual ~ApplicationManagerBase();
     virtual ~ApplicationManagerBase();
     ApplicationManager::BeforeRunStatus BeforeRun() override;
     ApplicationManager::BeforeRunStatus BeforeRun() override;
     void Destroy() override;
     void Destroy() override;

+ 11 - 1
Code/Tools/AssetProcessor/native/utilities/BatchApplicationManager.cpp

@@ -35,7 +35,17 @@ namespace BatchApplicationManagerPrivate
 #endif  //#if defined(AZ_PLATFORM_WINDOWS)
 #endif  //#if defined(AZ_PLATFORM_WINDOWS)
 
 
 BatchApplicationManager::BatchApplicationManager(int* argc, char*** argv, QObject* parent)
 BatchApplicationManager::BatchApplicationManager(int* argc, char*** argv, QObject* parent)
-    : ApplicationManagerBase(argc, argv, parent)
+    : BatchApplicationManager(argc, argv, parent, {})
+{
+}
+
+BatchApplicationManager::BatchApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : BatchApplicationManager(argc, argv, nullptr, AZStd::move(componentAppSettings))
+{
+}
+
+BatchApplicationManager::BatchApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
+    : ApplicationManagerBase(argc, argv, parent, AZStd::move(componentAppSettings))
 {
 {
     AssetProcessor::MessageInfoBus::Handler::BusConnect();
     AssetProcessor::MessageInfoBus::Handler::BusConnect();
 }
 }

+ 3 - 1
Code/Tools/AssetProcessor/native/utilities/BatchApplicationManager.h

@@ -22,7 +22,9 @@ class BatchApplicationManager
 {
 {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit BatchApplicationManager(int* argc, char*** argv, QObject* parent = 0);
+    BatchApplicationManager(int* argc, char*** argv, QObject* parent = nullptr);
+    BatchApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
+    BatchApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
     virtual ~BatchApplicationManager();
     virtual ~BatchApplicationManager();
 
 
     void Destroy() override;
     void Destroy() override;

+ 11 - 1
Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.cpp

@@ -94,7 +94,17 @@ void ErrorCollector::AddError(AZStd::string message)
 }
 }
 
 
 GUIApplicationManager::GUIApplicationManager(int* argc, char*** argv, QObject* parent)
 GUIApplicationManager::GUIApplicationManager(int* argc, char*** argv, QObject* parent)
-    : ApplicationManagerBase(argc, argv, parent)
+    : GUIApplicationManager(argc, argv, parent, {})
+{
+}
+
+GUIApplicationManager::GUIApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
+    : GUIApplicationManager(argc, argv, nullptr, AZStd::move(componentAppSettings))
+{
+}
+
+GUIApplicationManager::GUIApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings)
+    : ApplicationManagerBase(argc, argv, parent, AZStd::move(componentAppSettings))
 {
 {
 #if defined(AZ_PLATFORM_MAC)
 #if defined(AZ_PLATFORM_MAC)
     // Since AP is not shipped as a '.app' package, it will not receive keyboard focus
     // Since AP is not shipped as a '.app' package, it will not receive keyboard focus

+ 3 - 1
Code/Tools/AssetProcessor/native/utilities/GUIApplicationManager.h

@@ -51,7 +51,9 @@ class GUIApplicationManager
 {
 {
     Q_OBJECT
     Q_OBJECT
 public:
 public:
-    explicit GUIApplicationManager(int* argc, char*** argv, QObject* parent = 0);
+    GUIApplicationManager(int* argc, char*** argv, QObject* parent = nullptr);
+    GUIApplicationManager(int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
+    GUIApplicationManager(int* argc, char*** argv, QObject* parent, AZ::ComponentApplicationSettings componentAppSettings);
     ~GUIApplicationManager() override;
     ~GUIApplicationManager() override;
 
 
     ApplicationManager::BeforeRunStatus BeforeRun() override;
     ApplicationManager::BeforeRunStatus BeforeRun() override;

+ 10 - 1
Code/Tools/SerializeContextTools/Application.cpp

@@ -27,7 +27,16 @@ namespace AZ::SerializeContextTools
     //   it isn't used.
     //   it isn't used.
 
 
     Application::Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer)
     Application::Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer)
-        : AzToolsFramework::ToolsApplication(&argc, &argv)
+        : Application(argc, argv, stdoutCapturer, {})
+    {
+    }
+
+    Application::Application(int argc, char** argv, ComponentApplicationSettings componentAppSettings)
+        : Application(argc, argv, nullptr, AZStd::move(componentAppSettings))
+    {
+    }
+    Application::Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer, ComponentApplicationSettings componentAppSettings)
+        : AzToolsFramework::ToolsApplication(&argc, &argv, AZStd::move(componentAppSettings))
         , m_stdoutCapturer(stdoutCapturer)
         , m_stdoutCapturer(stdoutCapturer)
     {
     {
         // We need a specialized variant of EditorEntityContextComponent for the SliceConverter, so we register the descriptor here.
         // We need a specialized variant of EditorEntityContextComponent for the SliceConverter, so we register the descriptor here.

+ 2 - 0
Code/Tools/SerializeContextTools/Application.h

@@ -24,6 +24,8 @@ namespace AZ::SerializeContextTools
     public:
     public:
         AZ_CLASS_ALLOCATOR(Application, AZ::SystemAllocator)
         AZ_CLASS_ALLOCATOR(Application, AZ::SystemAllocator)
         Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer = {});
         Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer = {});
+        Application(int argc, char** argv, ComponentApplicationSettings componentAppSettings);
+        Application(int argc, char** argv, AZ::IO::FileDescriptorCapturer* stdoutCapturer, ComponentApplicationSettings componentAppSettings);
         ~Application() override = default;
         ~Application() override = default;
 
 
         const char* GetConfigFilePath() const;
         const char* GetConfigFilePath() const;

+ 1 - 0
Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h

@@ -45,6 +45,7 @@ namespace AtomToolsFramework
         using Base = AzFramework::Application;
         using Base = AzFramework::Application;
 
 
         AtomToolsApplication(const char* targetName, int* argc, char*** argv);
         AtomToolsApplication(const char* targetName, int* argc, char*** argv);
+        AtomToolsApplication(const char* targetName, int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings);
         ~AtomToolsApplication();
         ~AtomToolsApplication();
 
 
         virtual bool LaunchLocalServer();
         virtual bool LaunchLocalServer();

+ 6 - 1
Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp

@@ -48,8 +48,13 @@ namespace AtomToolsFramework
     AtomToolsApplication* AtomToolsApplication::m_instance = {};
     AtomToolsApplication* AtomToolsApplication::m_instance = {};
 
 
     AtomToolsApplication::AtomToolsApplication(const char* targetName, int* argc, char*** argv)
     AtomToolsApplication::AtomToolsApplication(const char* targetName, int* argc, char*** argv)
+        : AtomToolsApplication(targetName, argc, argv, {})
+    {
+    }
+
+    AtomToolsApplication::AtomToolsApplication(const char* targetName, int* argc, char*** argv, AZ::ComponentApplicationSettings componentAppSettings)
         : AzQtApplication(*argc, *argv)
         : AzQtApplication(*argc, *argv)
-        , Application(argc, argv)
+        , Application(argc, argv, AZStd::move(componentAppSettings))
         , m_targetName(targetName)
         , m_targetName(targetName)
         , m_toolId(targetName)
         , m_toolId(targetName)
     {
     {