Selaa lähdekoodia

Merge branch 'development' into PR_AP_UuidManagerHookup

# Conflicts:
#	Code/Tools/AssetProcessor/native/tests/assetmanager/AssetProcessorManagerTest.cpp
amzn-mike 2 vuotta sitten
vanhempi
commit
2dae24c830
100 muutettua tiedostoa jossa 1888 lisäystä ja 1116 poistoa
  1. 3 0
      AutomatedTesting/Gem/AssetProcessorGemConfig.setreg
  2. 6 0
      AutomatedTesting/Gem/PythonTests/Atom/tests/MaterialCanvas_Atom_BasicTests.py
  3. 2 2
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyAssetEditor.py
  4. 0 0
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyCommon.py
  5. 3 3
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyO3DEEditor.py
  6. 4 4
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasEditor.py
  7. 2 2
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasNodeInspector.py
  8. 0 0
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasNodePalette.py
  9. 0 0
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasVariableManager.py
  10. 6 0
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/__init__.py
  11. 2 1
      AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py
  12. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_config_backup_fixture.py
  13. 143 100
      AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py
  14. 43 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/CMakeLists.txt
  15. 7 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/__init__.py
  16. 213 190
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/asset_bundler_batch_tests.py
  17. 547 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab
  18. 12 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/tags.txt
  19. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Green_01.tif
  20. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Grey_01.tif
  21. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_White_01.tif
  22. 564 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/Canvas1.uicanvas
  23. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default1024.font
  24. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default2048.font
  25. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab1.prefab
  26. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab2.prefab
  27. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab1.prefab
  28. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab2.prefab
  29. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_corrupted_prefab/corrupted_prefab.prefab
  30. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab/working_prefab.prefab
  31. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab_override/working_prefab.prefab
  32. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_0.dat
  33. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_1.dat
  34. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_2.dat
  35. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_3.dat
  36. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_4.dat
  37. 3 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_5.dat
  38. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_0.txt
  39. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_1.txt
  40. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_2.txt
  41. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_3.txt
  42. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_4.txt
  43. 1 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_5.txt
  44. 0 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_in_editor_tests.py
  45. 4 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_tests.py
  46. 0 0
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/conftest.py
  47. 0 22
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt
  48. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py
  49. 1 1
      AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py
  50. 2 2
      AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py
  51. 7 11
      AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/pythonassetbuildertests.py
  52. 1 1
      AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py
  53. 1 1
      AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py
  54. 1 1
      AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py
  55. 2 2
      AutomatedTesting/Gem/PythonTests/scripting/VariableManager_ExposeVarsToComponent.py
  56. 1 1
      AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py
  57. 1 1
      CMakeLists.txt
  58. 117 12
      Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp
  59. 0 3
      Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h
  60. 1 26
      Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui
  61. 2 2
      Code/Editor/CMakeLists.txt
  62. 13 6
      Code/Editor/Controls/FolderTreeCtrl.cpp
  63. 2 14
      Code/Editor/CryEdit.cpp
  64. 0 1
      Code/Editor/CryEdit.h
  65. 0 17
      Code/Editor/Lib/Tests/test_Main.cpp
  66. 1 0
      Code/Editor/LyViewPaneNames.h
  67. 0 1
      Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp
  68. 0 2
      Code/Editor/Plugins/ComponentEntityEditorPlugin/Tests/test_Main.cpp
  69. 6 9
      Code/Editor/PythonEditorFuncs.cpp
  70. 0 3
      Code/Editor/main.cpp
  71. 0 4
      Code/Framework/AtomCore/Tests/InstanceDatabase.cpp
  72. 0 4
      Code/Framework/AtomCore/Tests/Main.cpp
  73. 0 2
      Code/Framework/AzCore/AzCore/AzCoreModule.cpp
  74. 13 69
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp
  75. 2 12
      Code/Framework/AzCore/AzCore/Component/ComponentApplication.h
  76. 9 6
      Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.cpp
  77. 7 1
      Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.h
  78. 9 3
      Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.cpp
  79. 11 3
      Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.h
  80. 0 1
      Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp
  81. 4 5
      Code/Framework/AzCore/AzCore/Memory/AllocationRecords.cpp
  82. 2 1
      Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h
  83. 0 37
      Code/Framework/AzCore/AzCore/Memory/AllocatorInstance.h
  84. 0 131
      Code/Framework/AzCore/AzCore/Memory/MemoryComponent.cpp
  85. 0 58
      Code/Framework/AzCore/AzCore/Memory/MemoryComponent.h
  86. 5 9
      Code/Framework/AzCore/AzCore/Serialization/SerializeContext.cpp
  87. 0 19
      Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h
  88. 0 6
      Code/Framework/AzCore/AzCore/UserSettings/UserSettingsComponent.cpp
  89. 0 2
      Code/Framework/AzCore/AzCore/UserSettings/UserSettingsComponent.h
  90. 0 2
      Code/Framework/AzCore/AzCore/azcore_files.cmake
  91. 0 6
      Code/Framework/AzCore/Tests/AZStd/VariantSerialization.cpp
  92. 0 12
      Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp
  93. 3 14
      Code/Framework/AzCore/Tests/Components.cpp
  94. 0 2
      Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp
  95. 27 0
      Code/Framework/AzCore/Tests/Debug/PerformanceCollectorTests.cpp
  96. 0 4
      Code/Framework/AzCore/Tests/EBus.cpp
  97. 0 12
      Code/Framework/AzCore/Tests/Jobs.cpp
  98. 0 72
      Code/Framework/AzCore/Tests/Memory.cpp
  99. 28 166
      Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp
  100. 0 10
      Code/Framework/AzCore/Tests/Memory/HphaAllocator.cpp

+ 3 - 0
AutomatedTesting/Gem/AssetProcessorGemConfig.setreg

@@ -17,6 +17,9 @@
                 "Exclude Restricted AssetProcessorTestAssets": {
                 "Exclude Restricted AssetProcessorTestAssets": {
                     "glob": "*/asset_processor_tests/restricted/*"
                     "glob": "*/asset_processor_tests/restricted/*"
                 },
                 },
+                "Exclude AssetBundlerTestAssets": {
+                    "glob": "*/asset_bundler_tests/assets/*"
+                },
                 "Exclude Scene Tests": {
                 "Exclude Scene Tests": {
                     "glob": "*/scene_tests/assets/*"
                     "glob": "*/scene_tests/assets/*"
                 }
                 }

+ 6 - 0
AutomatedTesting/Gem/PythonTests/Atom/tests/MaterialCanvas_Atom_BasicTests.py

@@ -53,11 +53,17 @@ def MaterialCanvas_BasicFunctionalityChecks_AllChecksPass():
 
 
     import os
     import os
 
 
+    import azlmbr.atomtools.util
     import Atom.atom_utils.atom_tools_utils as atom_tools_utils
     import Atom.atom_utils.atom_tools_utils as atom_tools_utils
     import Atom.atom_utils.material_canvas_utils as material_canvas_utils
     import Atom.atom_utils.material_canvas_utils as material_canvas_utils
     from editor_python_test_tools.utils import Report, Tracer, TestHelper
     from editor_python_test_tools.utils import Report, Tracer, TestHelper
 
 
     with Tracer() as error_tracer:
     with Tracer() as error_tracer:
+        # Disable automatic material and shader generation when opening graphs.
+        azlmbr.atomtools.util.SetSettingsValue_bool("/O3DE/AtomToolsFramework/GraphCompiler/CompileOnOpen", False)
+        azlmbr.atomtools.util.SetSettingsValue_bool("/O3DE/AtomToolsFramework/GraphCompiler/CompileOnSave", False)
+        azlmbr.atomtools.util.SetSettingsValue_bool("/O3DE/AtomToolsFramework/GraphCompiler/CompileOnEdit", False)
+
         # Set constants before starting test steps.
         # Set constants before starting test steps.
         test_1_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test1.materialgraph")
         test_1_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test1.materialgraph")
         test_2_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test2.materialgraph")
         test_2_material_graph = os.path.join(atom_tools_utils.MATERIALCANVAS_GRAPH_PATH, "test2.materialgraph")

+ 2 - 2
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyAssetEditor.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyAssetEditor.py

@@ -8,12 +8,12 @@ Object to house all the Qt Objects and behavior used in testing the asset editor
 """
 """
 
 
 from editor_python_test_tools.utils import TestHelper as helper
 from editor_python_test_tools.utils import TestHelper as helper
-from PySide2 import QtWidgets, QtCore, QtTest
+from PySide2 import QtWidgets
 import pyside_utils
 import pyside_utils
 import azlmbr.editor as editor
 import azlmbr.editor as editor
 import azlmbr.bus as bus
 import azlmbr.bus as bus
 import os
 import os
-from editor_python_test_tools.QtPyCommon import QtPyCommon
+from editor_python_test_tools.QtPy.QtPyCommon import QtPyCommon
 from consts.asset_editor import (ASSET_EDITOR_UI, EVENTS_QT, DEFAULT_SCRIPT_EVENT, DEFAULT_METHOD_NAME)
 from consts.asset_editor import (ASSET_EDITOR_UI, EVENTS_QT, DEFAULT_SCRIPT_EVENT, DEFAULT_METHOD_NAME)
 from consts.general import (WAIT_TIME_SEC_3, SAVE_STRING)
 from consts.general import (WAIT_TIME_SEC_3, SAVE_STRING)
 
 

+ 0 - 0
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyCommon.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyCommon.py


+ 3 - 3
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyO3DEEditor.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyO3DEEditor.py

@@ -7,9 +7,9 @@ SPDX-License-Identifier: Apache-2.0 OR MIT
 Object to house all the Qt Objects used when testing and manipulating the O3DE UI
 Object to house all the Qt Objects used when testing and manipulating the O3DE UI
 """
 """
 import pyside_utils
 import pyside_utils
-from editor_python_test_tools.QtPyCommon import QtPyCommon
-from editor_python_test_tools.QtPyScriptCanvasEditor import QtPyScriptCanvasEditor
-from editor_python_test_tools.QtPyAssetEditor import QtPyAssetEditor
+from editor_python_test_tools.QtPy.QtPyCommon import QtPyCommon
+from editor_python_test_tools.QtPy.QtPyScriptCanvasEditor import QtPyScriptCanvasEditor
+from editor_python_test_tools.QtPy.QtPyAssetEditor import QtPyAssetEditor
 import azlmbr.legacy.general as general
 import azlmbr.legacy.general as general
 from editor_python_test_tools.utils import TestHelper
 from editor_python_test_tools.utils import TestHelper
 from consts.asset_editor import (ASSET_EDITOR_UI)
 from consts.asset_editor import (ASSET_EDITOR_UI)

+ 4 - 4
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyScriptCanvasEditor.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasEditor.py

@@ -8,10 +8,10 @@ Object to house all the Qt Objects used when testing and manipulating the Script
 """
 """
 from PySide2 import QtWidgets
 from PySide2 import QtWidgets
 import pyside_utils
 import pyside_utils
-from editor_python_test_tools.QtPyCommon import QtPyCommon
-from editor_python_test_tools.QtPyScriptCanvasVariableManager import QtPyScriptCanvasVariableManager
-from editor_python_test_tools.QtPyScriptCanvasNodePalette import QtPyScriptCanvasNodePalette
-from editor_python_test_tools.QtPyScriptCanvasNodeInspector import QtPyScriptCanvasNodeInspector
+from editor_python_test_tools.QtPy.QtPyCommon import QtPyCommon
+from editor_python_test_tools.QtPy.QtPyScriptCanvasVariableManager import QtPyScriptCanvasVariableManager
+from editor_python_test_tools.QtPy.QtPyScriptCanvasNodePalette import QtPyScriptCanvasNodePalette
+from editor_python_test_tools.QtPy.QtPyScriptCanvasNodeInspector import QtPyScriptCanvasNodeInspector
 from consts.scripting import (SCRIPT_CANVAS_UI)
 from consts.scripting import (SCRIPT_CANVAS_UI)
 
 
 
 

+ 2 - 2
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyScriptCanvasNodeInspector.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasNodeInspector.py

@@ -10,8 +10,8 @@ Object to house all the Qt Objects and behavior used in testing the script canva
 """
 """
 
 
 from editor_python_test_tools.utils import TestHelper as helper
 from editor_python_test_tools.utils import TestHelper as helper
-from PySide2 import QtWidgets, QtTest, QtCore
-from editor_python_test_tools.QtPyCommon import CheckBoxStates
+from PySide2 import QtWidgets
+from editor_python_test_tools.QtPy.QtPyCommon import CheckBoxStates
 from consts.scripting import (PROPERTY_EDITOR_QT, INITIAL_VALUE_SOURCE_QT, NODE_INSPECTOR_QT)
 from consts.scripting import (PROPERTY_EDITOR_QT, INITIAL_VALUE_SOURCE_QT, NODE_INSPECTOR_QT)
 from consts.general import (WAIT_TIME_SEC_3)
 from consts.general import (WAIT_TIME_SEC_3)
 from enum import IntEnum
 from enum import IntEnum

+ 0 - 0
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyScriptCanvasNodePalette.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasNodePalette.py


+ 0 - 0
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPyScriptCanvasVariableManager.py → AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/QtPyScriptCanvasVariableManager.py


+ 6 - 0
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/QtPy/__init__.py

@@ -0,0 +1,6 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""

+ 2 - 1
AutomatedTesting/Gem/PythonTests/EditorPythonTestTools/editor_python_test_tools/utils.py

@@ -190,6 +190,7 @@ class TestHelper:
         with MultiplayerHelper() as multiplayer_helper:
         with MultiplayerHelper() as multiplayer_helper:
             # enter game-mode. 
             # enter game-mode. 
             # game-mode in multiplayer will also launch ServerLauncher.exe and connect to the editor
             # game-mode in multiplayer will also launch ServerLauncher.exe and connect to the editor
+            general.set_cvar_integer('editorsv_max_connection_attempts', 15)
             multiplayer.PythonEditorFuncs_enter_game_mode()
             multiplayer.PythonEditorFuncs_enter_game_mode()
 
 
             # make sure the server launcher is running
             # make sure the server launcher is running
@@ -200,7 +201,7 @@ class TestHelper:
             TestHelper.wait_for_condition(lambda : multiplayer_helper.editorConnectionAttemptCount > 0, 10.0)
             TestHelper.wait_for_condition(lambda : multiplayer_helper.editorConnectionAttemptCount > 0, 10.0)
             Report.critical_result(("Multiplayer Editor attempting server connection.", "Multiplayer Editor never tried connecting to the server."), multiplayer_helper.editorConnectionAttemptCount > 0)
             Report.critical_result(("Multiplayer Editor attempting server connection.", "Multiplayer Editor never tried connecting to the server."), multiplayer_helper.editorConnectionAttemptCount > 0)
 
 
-            TestHelper.wait_for_condition(lambda : multiplayer_helper.editorSendingLevelData, 10.0)
+            TestHelper.wait_for_condition(lambda : multiplayer_helper.editorSendingLevelData, 106.0)
             Report.critical_result(("Multiplayer Editor sent level data to the server.", "Multiplayer Editor never sent the level to the server."), multiplayer_helper.editorSendingLevelData)
             Report.critical_result(("Multiplayer Editor sent level data to the server.", "Multiplayer Editor never sent the level to the server."), multiplayer_helper.editorSendingLevelData)
 
 
             TestHelper.wait_for_condition(lambda : multiplayer_helper.connectToSimulationSuccess, 10.0)
             TestHelper.wait_for_condition(lambda : multiplayer_helper.connectToSimulationSuccess, 10.0)

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/ap_config_backup_fixture.py

@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
 
 
 SPDX-License-Identifier: Apache-2.0 OR MIT
 SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-Fixture for backing up and restoring dev/AssetProcessorPlatformConfig.ini
+Fixture for backing up and restoring <EngineRoot>\Registry\AssetProcessorPlatformConfig.setreg
 
 
 """
 """
 
 

+ 143 - 100
AutomatedTesting/Gem/PythonTests/assetpipeline/ap_fixtures/bundler_batch_setup_fixture.py

@@ -17,9 +17,10 @@ import logging
 import zipfile
 import zipfile
 from typing import Any, Dict, List
 from typing import Any, Dict, List
 
 
-from . import asset_processor_fixture as asset_processor
-from . import timeout_option_fixture as timeout
-from . import ap_config_backup_fixture as config_backup
+from assetpipeline.ap_fixtures.asset_processor_fixture import asset_processor
+from assetpipeline.ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
+from assetpipeline.ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as config_backup
+from assetpipeline.ap_fixtures.ap_setup_fixture import ap_setup_fixture
 
 
 import ly_test_tools.environment.file_system as fs
 import ly_test_tools.environment.file_system as fs
 import ly_test_tools.o3de.pipeline_utils as utils
 import ly_test_tools.o3de.pipeline_utils as utils
@@ -30,67 +31,102 @@ logger = logging.getLogger(__name__)
 
 
 @pytest.fixture
 @pytest.fixture
 @pytest.mark.usefixtures("config_backup")
 @pytest.mark.usefixtures("config_backup")
-def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) -> Any:
-
-    ALL_PLATFORMS = []
-    for _, value in ASSET_PROCESSOR_PLATFORM_MAP.items():
-        ALL_PLATFORMS.append(value)
-
-    # Set up temporary directory to use for tests
-    tempDir = os.path.join(TF.gettempdir(), "AssetBundlerTempDirectory")
-    if os.path.exists(tempDir):
-        fs.delete([tempDir], True, True)
-    if not os.path.exists(tempDir):
-        os.mkdir(tempDir)
-
-    # Get platforms to build for bundle tests
-    platforms = request.config.getoption("--bundle_platforms")
-    if platforms is not None:
-        # Remove whitespace and split at commas if platforms provided
-        platforms = [platform.strip() for platform in platforms.split(",")]
-    else:
-        # No commandline argument provided, default to mac and pc
-        platforms = ["pc", "mac"]
-
-    class BundlerBatchFixture:
[email protected]("asset_processor")
[email protected]("ap_setup_fixture")
+def bundler_batch_setup_fixture(request, workspace, ap_setup_fixture, asset_processor, timeout) -> Any:
+
+    def get_all_platforms() -> list[str]:
+        """Helper: This function generates a list of all platforms to be built for testing Asset Bundler."""
+        ALL_PLATFORMS = []
+        for _, value in ASSET_PROCESSOR_PLATFORM_MAP.items():
+            ALL_PLATFORMS.append(value)
+        return ALL_PLATFORMS
+
+    def platforms_to_build() -> list | list[str]:
+        """Helper: Gets the platforms to build for bundle tests."""
+        platforms = request.config.getoption("--bundle_platforms")
+        if platforms is not None:
+            # Remove whitespace and split at commas if platforms provided
+            platforms = [platform.strip() for platform in platforms.split(",")]
+        else:
+            # No commandline argument provided, default to mac and pc
+            platforms = ["pc", "mac"]
+        return platforms
+
+    def setup_temp_workspace() -> None:
+        """Helper: Sets up the temp workspace for asset bundling tests."""
+        asset_processor.create_temp_asset_root()
+
+    def setup_temp_dir() -> Any:
+        """Helper: Sets up a temp directory for use in bundling tests that can't use the temp workspace."""
+        tempDir = os.path.join(TF.gettempdir(), "AssetBundlerTempDirectory")
+        if os.path.exists(tempDir):
+            fs.delete([tempDir], True, True)
+        if not os.path.exists(tempDir):
+            os.mkdir(tempDir)
+        return tempDir
+
+    class WorkSpaceBundlerBatchFixture:
         """
         """
         Houses useful variables and functions for running Asset Bundler Batch Tests
         Houses useful variables and functions for running Asset Bundler Batch Tests
         """
         """
-
         def __init__(self):
         def __init__(self):
             self.bin_dir = workspace.paths.build_directory()
             self.bin_dir = workspace.paths.build_directory()
             self.bundler_batch = os.path.join(self.bin_dir, "AssetBundlerBatch")
             self.bundler_batch = os.path.join(self.bin_dir, "AssetBundlerBatch")
-            self.test_dir = tempDir
-            self.asset_alias = workspace.paths.platform_cache()
-            self.tools_dir = os.path.join(workspace.paths.engine_root(), "Tools")
             self.seed_list_file_name = "testSeedListFile.seed"
             self.seed_list_file_name = "testSeedListFile.seed"
-            self.seed_list_file = os.path.join(self.test_dir, self.seed_list_file_name)
             self.asset_info_file_name = "assetFileInfo.assetlist"
             self.asset_info_file_name = "assetFileInfo.assetlist"
-            self.asset_info_file_request = os.path.join(self.test_dir, self.asset_info_file_name)
-            self.bundle_settings_file_request = os.path.join(self.test_dir, "bundleSettingsFile.bundlesettings")
             self.bundle_file_name = "bundle.pak"
             self.bundle_file_name = "bundle.pak"
-            self.bundle_file = os.path.join(self.test_dir, self.bundle_file_name)
-            self.asset_info_file_result = os.path.join(
-                self.test_dir, self.platform_file_name(self.asset_info_file_name,
-                                                       workspace.asset_processor_platform)
-            )
-            self.bundle_settings_file_result = os.path.join(
-                self.test_dir, self.platform_file_name("bundleSettingsFile.bundlesettings",
-                                                       workspace.asset_processor_platform)
-            )
+            self.bundle_settings_file_name = "bundleSettingsFile.bundlesettings"
+            self.workspace = workspace
+            self.platforms = platforms_to_build()
+            self.platforms_as_string = ",".join(self.platforms)
+
             # Useful sizes
             # Useful sizes
             self.max_bundle_size_in_mib = 35
             self.max_bundle_size_in_mib = 35
             self.number_of_bytes_in_mib = 1024 * 1024
             self.number_of_bytes_in_mib = 1024 * 1024
-            self.workspace = workspace
-            self.platforms = platforms
-            self.platforms_as_string = ",".join(platforms)
-
-        # *** Bundler-batch-calling helpers ***
 
 
-        def call_asset_bundler(self, arg_list):                 
-            # Print out the call to asset bundler, so if an error occurs, the commands that were run can be repeated.
-            # Split out the list to something that can be easily copy and pasted. Printing a list by default will put it in,
-            # [comma, separated, braces], this join will instead print each arg in the list with only a space between them.
+            # Checks whether or not the fixture was parametrized to use the temp workspace. Defaults to True.
+            self.use_temp_workspace = request.param if hasattr(request, "param") else True
+
+            if self.use_temp_workspace:
+                setup_temp_workspace()
+                self.project_path = os.path.join(asset_processor.temp_asset_root(), workspace.project)
+                self.cache = asset_processor.temp_project_cache_path()
+                self.seed_list_file = os.path.join(self.project_path, self.seed_list_file_name)
+                self.asset_info_file_request = os.path.join(self.project_path, self.asset_info_file_name)
+                self.bundle_settings_file_request = os.path.join(self.project_path, self.bundle_settings_file_name)
+                self.bundle_file = os.path.join(self.project_path, self.bundle_file_name)
+                self.asset_info_file_result = os.path.join(
+                    self.project_path, self.platform_file_name(self.asset_info_file_name,
+                                                               workspace.asset_processor_platform)
+                )
+                self.bundle_settings_file_result = os.path.join(
+                    self.project_path, self.platform_file_name(self.bundle_settings_file_name,
+                                                               workspace.asset_processor_platform)
+                )
+
+            else:
+                self.project_path = workspace.paths.project()
+                self.cache = workspace.paths.project_cache()
+                self.test_dir = setup_temp_dir()
+                self.seed_list_file = os.path.join(self.test_dir, self.seed_list_file_name)
+                self.asset_info_file_request = os.path.join(self.test_dir, self.asset_info_file_name)
+                self.bundle_settings_file_request = os.path.join(self.test_dir, self.bundle_settings_file_name)
+                self.bundle_file = os.path.join(self.test_dir, self.bundle_file_name)
+                self.asset_info_file_result = os.path.join(
+                    self.test_dir, self.platform_file_name(self.asset_info_file_name,
+                                                           workspace.asset_processor_platform)
+                )
+                self.bundle_settings_file_result = os.path.join(
+                    self.test_dir, self.platform_file_name(self.bundle_settings_file_name,
+                                                           workspace.asset_processor_platform)
+                )
+
+        @staticmethod
+        def call_asset_bundler(arg_list):
+            """
+            Prints out the call to asset bundler, so if an error occurs, the commands that were run can be repeated.
+            """
             logger.info(f"{' '.join(f'arg_list{x}' for x in arg_list)}")
             logger.info(f"{' '.join(f'arg_list{x}' for x in arg_list)}")
             try:
             try:
                 output = subprocess.check_output(arg_list).decode()
                 output = subprocess.check_output(arg_list).decode()
@@ -103,48 +139,48 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 logger.error(f"File Not Found - Failed to call AssetBundlerBatch with args {arg_list} with error {e}")
                 logger.error(f"File Not Found - Failed to call AssetBundlerBatch with args {arg_list} with error {e}")
                 raise e
                 raise e
 
 
-        def call_bundlerbatch(self, **kwargs: Dict[str, str]):
+        def call_bundlerbatch(self, **kwargs: Dict[str, str]) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with no sub-command"""
             """Helper function for calling assetbundlerbatch with no sub-command"""
             cmd = [self.bundler_batch]
             cmd = [self.bundler_batch]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_seeds(self, **kwargs: Dict[str, str]) -> None:
+        def call_seeds(self, **kwargs: Dict[str, str]) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'seeds' sub-command"""
             """Helper function for calling assetbundlerbatch with 'seeds' sub-command"""
 
 
             cmd = [self.bundler_batch, "seeds"]
             cmd = [self.bundler_batch, "seeds"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_assetLists(self, **kwargs: Dict) -> None:
+        def call_assetLists(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'assetLists' sub-command"""
             """Helper function for calling assetbundlerbatch with 'assetLists' sub-command"""
 
 
             cmd = [self.bundler_batch, "assetLists"]
             cmd = [self.bundler_batch, "assetLists"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_comparisonRules(self, **kwargs: Dict) -> None:
+        def call_comparisonRules(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'comparisonRules' sub-command"""
             """Helper function for calling assetbundlerbatch with 'comparisonRules' sub-command"""
 
 
             cmd = [self.bundler_batch, "comparisonRules"]
             cmd = [self.bundler_batch, "comparisonRules"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_compare(self, **kwargs: Dict) -> None:
+        def call_compare(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'compare' sub-command"""
             """Helper function for calling assetbundlerbatch with 'compare' sub-command"""
 
 
             cmd = [self.bundler_batch, "compare"]
             cmd = [self.bundler_batch, "compare"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_bundleSettings(self, **kwargs: Dict) -> None:
+        def call_bundleSettings(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundleSettings' sub-command"""
             """Helper function for calling assetbundlerbatch with 'bundleSettings' sub-command"""
 
 
             cmd = [self.bundler_batch, "bundleSettings"]
             cmd = [self.bundler_batch, "bundleSettings"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_bundles(self, **kwargs: Dict) -> None:
+        def call_bundles(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundles' sub-command"""
             """Helper function for calling assetbundlerbatch with 'bundles' sub-command"""
 
 
             cmd = [self.bundler_batch, "bundles"]
             cmd = [self.bundler_batch, "bundles"]
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
             return self.call_asset_bundler(self._append_arguments(cmd, kwargs))
 
 
-        def call_bundleSeed(self, **kwargs: Dict) -> None:
+        def call_bundleSeed(self, **kwargs: Dict) -> tuple[bool, str] | tuple[bool, Any]:
             """Helper function for calling assetbundlerbatch with 'bundleSeed' sub-command"""
             """Helper function for calling assetbundlerbatch with 'bundleSeed' sub-command"""
 
 
             cmd = [self.bundler_batch, "bundleSeed"]
             cmd = [self.bundler_batch, "bundleSeed"]
@@ -153,17 +189,22 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
         def _append_arguments(self, cmd: List[str], kwargs: Dict, append_defaults: bool = True) -> List[str]:
         def _append_arguments(self, cmd: List[str], kwargs: Dict, append_defaults: bool = True) -> List[str]:
             """Appends and returns all keyword arguments to the list of string [cmd]"""
             """Appends and returns all keyword arguments to the list of string [cmd]"""
             for key, value in kwargs.items():
             for key, value in kwargs.items():
-                if value:
-                    cmd.append(f"--{key}={value}")
-                else:
+                if not value:
                     cmd.append(f"--{key}")
                     cmd.append(f"--{key}")
+
+                else:
+                    if type(value) != list:
+                        cmd.append(f"--{key}={value}")
+                    else:
+                        for item in value:
+                            cmd.append(f"--{key}={item}")
+
             if append_defaults:
             if append_defaults:
-                cmd.append(f"--project-path={workspace.paths.project()}")
+                cmd.append(f"--project-path={self.project_path}")
             return cmd
             return cmd
 
 
-        # ******
-
-        def get_seed_relative_paths(self, seed_file: str) -> str:
+        @staticmethod
+        def get_seed_relative_paths(seed_file: str) -> str:
             """Iterates all asset relative paths in the [seed_file]."""
             """Iterates all asset relative paths in the [seed_file]."""
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             # Get value from all XML nodes who are grandchildren of all Class tags and have
             # Get value from all XML nodes who are grandchildren of all Class tags and have
@@ -171,7 +212,8 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             for node in ET.parse(seed_file).getroot().findall(r"./Class/Class/*[@field='pathHint']"):
             for node in ET.parse(seed_file).getroot().findall(r"./Class/Class/*[@field='pathHint']"):
                 yield node.attrib["value"]
                 yield node.attrib["value"]
 
 
-        def get_seed_relative_paths_for_platform(self, seed_file: str, platform_flags : int) -> str:
+        @staticmethod
+        def get_seed_relative_paths_for_platform(seed_file: str, platform_flags: int) -> list[str]:
             """Iterates all asset relative paths in the [seed_file] which match the platform flags"""
             """Iterates all asset relative paths in the [seed_file] which match the platform flags"""
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             assert seed_file.endswith(".seed"), f"file {seed_file} is not a seed file"
             # Get value from all XML nodes who are grandchildren of all Class tags and have
             # Get value from all XML nodes who are grandchildren of all Class tags and have
@@ -182,30 +224,32 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             root = data.getroot()
             root = data.getroot()
             seedFileRootNode = root.find("Class")
             seedFileRootNode = root.find("Class")
             for seedFileInfoNode in seedFileRootNode.findall("*"):
             for seedFileInfoNode in seedFileRootNode.findall("*"):
-                if (int(seedFileInfoNode.find('./Class[@field="platformFlags"]').attrib["value"]) & platform_flags ):
+                if (int(seedFileInfoNode.find('./Class[@field="platformFlags"]').attrib["value"]) & platform_flags):
                     pathHint = seedFileInfoNode.find('./Class[@field="pathHint"]').attrib["value"]
                     pathHint = seedFileInfoNode.find('./Class[@field="pathHint"]').attrib["value"]
                     seedFileListContents.append(pathHint)
                     seedFileListContents.append(pathHint)
             return seedFileListContents
             return seedFileListContents
 
 
-        def get_asset_relative_paths(self, asset_list_file: str) -> str:
+        @staticmethod
+        def get_asset_relative_paths(asset_list_file: str) -> str:
             """Iterates all asset relative paths in the [asset_list_file]."""
             """Iterates all asset relative paths in the [asset_list_file]."""
             assert asset_list_file.endswith(".assetlist"), f"file {asset_list_file} is not an assetlist file"
             assert asset_list_file.endswith(".assetlist"), f"file {asset_list_file} is not an assetlist file"
             # Get value from all XML nodes who are great-grandchildren of all Class tags and have
             # Get value from all XML nodes who are great-grandchildren of all Class tags and have
             # a field attr. equal to "assetRelativePath"
             # a field attr. equal to "assetRelativePath"
-            # fmt:off
+
             for node in (ET.parse(asset_list_file).getroot().findall(
             for node in (ET.parse(asset_list_file).getroot().findall(
                     r"./Class/Class/Class/*[@field='assetRelativePath']")):
                     r"./Class/Class/Class/*[@field='assetRelativePath']")):
                 yield node.attrib["value"]
                 yield node.attrib["value"]
-            # fmt:on
 
 
-        def get_dependent_bundle_names(self, manifest_file: str) -> str:
+        @staticmethod
+        def get_dependent_bundle_names(manifest_file: str) -> str:
             """Iterates all dependent bundle names in the [manifest_file]"""
             """Iterates all dependent bundle names in the [manifest_file]"""
             assert manifest_file.endswith(".xml"), f"File {manifest_file} does not have an XML extension"
             assert manifest_file.endswith(".xml"), f"File {manifest_file} does not have an XML extension"
             # Get value from all XML nodes whose parent field attr. is "DependentBundleNames" and whose tag is Class
             # Get value from all XML nodes whose parent field attr. is "DependentBundleNames" and whose tag is Class
             for node in ET.parse(manifest_file).getroot().findall(r".//*[@field='DependentBundleNames']/Class"):
             for node in ET.parse(manifest_file).getroot().findall(r".//*[@field='DependentBundleNames']/Class"):
                 yield node.attrib["value"]
                 yield node.attrib["value"]
 
 
-        def platform_file_name(self, file_name: str, platform: str) -> str:
+        @staticmethod
+        def platform_file_name(file_name: str, platform: str) -> str:
             """Converts the standard [file_name] to a platform specific file name"""
             """Converts the standard [file_name] to a platform specific file name"""
             split = file_name.split(".", 1)
             split = file_name.split(".", 1)
             platform_name = ASSET_PROCESSOR_PLATFORM_MAP.get(platform)
             platform_name = ASSET_PROCESSOR_PLATFORM_MAP.get(platform)
@@ -214,14 +258,16 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 return file_name
                 return file_name
             return f'{split[0]}_{platform_name}.{split[1]}'
             return f'{split[0]}_{platform_name}.{split[1]}'
 
 
-        def extract_file_content(self, bundle_file: str, file_name_to_extract: str) -> str:
-            """Extract the contents of a single file from a bundle"""
+        @staticmethod
+        def extract_file_content(bundle_file: str, file_name_to_extract: str) -> bytes:
+            """Extract the contents of a single file from a bundle as a ByteString."""
 
 
             with zipfile.ZipFile(bundle_file) as bundle_zip:
             with zipfile.ZipFile(bundle_file) as bundle_zip:
                 with bundle_zip.open(file_name_to_extract, "r") as extracted_file:
                 with bundle_zip.open(file_name_to_extract, "r") as extracted_file:
                     return extracted_file.read()
                     return extracted_file.read()
 
 
-        def get_crc_of_files_in_archive(self, archive_name: str) -> Dict[str, int]:
+        @staticmethod
+        def get_crc_of_files_in_archive(archive_name: str) -> Dict[str, int]:
             """
             """
             Extracts the CRC-32 'checksum' for all files in the archive as dictionary.
             Extracts the CRC-32 'checksum' for all files in the archive as dictionary.
             The returned dictionary will have:
             The returned dictionary will have:
@@ -234,17 +280,20 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
                 file_crcs[info.filename] = info.CRC
                 file_crcs[info.filename] = info.CRC
             return file_crcs
             return file_crcs
 
 
-        def get_platform_flag(self, platform_name: str) -> int:
-            if (platform_name == "pc"):
-                return 1
-            elif (platform_name == "android"):
-                return 2
-            elif (platform_name == "ios"):
-                return 4
-            elif (platform_name == "mac"):
-                return 8
-            elif (platform_name == "server"):
-                return 128
+        @staticmethod
+        def get_platform_flag(platform_name: str) -> int:
+            """ Helper to fetch the platform flag from a provided platform name. """
+            platform_flags = {
+                "pc": 1,
+                "android": 2,
+                "ios": 4,
+                "mac": 8,
+                "server": 128
+            }
+            if platform_name in platform_flags:
+                return platform_flags.get(platform_name)
+            raise ValueError(f"{platform_name} not found within expected platform flags. "
+                             f"Expected: {platform_flags.keys()}")
 
 
         def extract_and_check(self, extract_dir: str, bundle_file: str) -> None:
         def extract_and_check(self, extract_dir: str, bundle_file: str) -> None:
             """
             """
@@ -287,7 +336,8 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
             # Ensure that all assets were present in the bundles
             # Ensure that all assets were present in the bundles
             assert sorted(assets_from_file) == sorted(assets_in_disk)
             assert sorted(assets_from_file) == sorted(assets_in_disk)
 
 
-        def _get_platform_flags(self) -> Dict[str, int]:
+        @staticmethod
+        def _get_platform_flags() -> Dict[str, int]:
             """
             """
             Extract platform numeric values from the file that declares them (PlatformDefaults.h):
             Extract platform numeric values from the file that declares them (PlatformDefaults.h):
             Platform Flags are defined in the C header file, where ORDER MATTERS.
             Platform Flags are defined in the C header file, where ORDER MATTERS.
@@ -324,7 +374,10 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
 
 
         def teardown(self) -> None:
         def teardown(self) -> None:
             """Destroys the temporary directory used in this test"""
             """Destroys the temporary directory used in this test"""
-            fs.delete([self.test_dir], True, True)
+            if self.use_temp_workspace:
+                fs.delete([asset_processor.temp_asset_root()], True, True)
+            else:
+                fs.delete([self.test_dir], True, True)
 
 
         def __getitem__(self, item: str) -> str:
         def __getitem__(self, item: str) -> str:
             """Get Item overload to use the object like a dictionary.
             """Get Item overload to use the object like a dictionary.
@@ -333,19 +386,9 @@ def bundler_batch_setup_fixture(request, workspace, asset_processor, timeout) ->
 
 
     # End class BundlerBatchFixture
     # End class BundlerBatchFixture
 
 
-    bundler_batch_fixture = BundlerBatchFixture()
+    bundler_batch_fixture = WorkSpaceBundlerBatchFixture()
     request.addfinalizer(bundler_batch_fixture.teardown)
     request.addfinalizer(bundler_batch_fixture.teardown)
 
 
     bundler_batch_fixture.platform_values = bundler_batch_fixture._get_platform_flags()
     bundler_batch_fixture.platform_values = bundler_batch_fixture._get_platform_flags()
 
 
-    # Enable platforms accepted from command line
-    platforms_list = [platform for platform in platforms if platform in ALL_PLATFORMS]
-
-    # Run a full scan to ENSURE that both caches (pc and osx) are COMPLETELY POPULATED
-    # Needed for asset bundling
-    # fmt:off
-    assert asset_processor.batch_process(fastscan=True, timeout=timeout * len(platforms), platforms=platforms_list), \
-        "AP Batch failed to process in bundler_batch_fixture"
-    # fmt:on
-
     return bundler_batch_fixture  # Return the fixture
     return bundler_batch_fixture  # Return the fixture

+ 43 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/CMakeLists.txt

@@ -0,0 +1,43 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#
+
+if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
+## AP Python Tests ##
+
+## Non-Linux Tests ##
+
+    set(SUPPORTED_PLATFORMS "Windows" "Mac")
+    if (NOT "${PAL_PLATFORM_NAME}" IN_LIST SUPPORTED_PLATFORMS)
+        return()
+    endif()
+
+## Periodic Tests ##
+
+    ly_add_pytest(
+        NAME APTests.AssetBundler
+        PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
+        TEST_SERIAL 
+        TEST_SUITE periodic
+        RUNTIME_DEPENDENCIES
+            AZ::AssetProcessor
+            AZ::AssetBundlerBatch
+    )
+
+    ly_add_pytest(
+        NAME APTests.BundleMode
+        PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
+        TEST_SERIAL
+        TEST_SUITE periodic
+        RUNTIME_DEPENDENCIES
+            AZ::AssetProcessor
+            AZ::AssetBundlerBatch
+            Legacy::Editor
+            AutomatedTesting.Assets
+    )
+
+endif()

+ 7 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/__init__.py

@@ -0,0 +1,7 @@
+#
+# Copyright (c) Contributors to the Open 3D Engine Project.
+# For complete copyright and license terms please see the LICENSE at the root of this distribution.
+#
+# SPDX-License-Identifier: Apache-2.0 OR MIT
+#
+#

+ 213 - 190
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_bundler_batch_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/asset_bundler_batch_tests.py

@@ -4,7 +4,7 @@ For complete copyright and license terms please see the LICENSE at the root of t
 
 
 SPDX-License-Identifier: Apache-2.0 OR MIT
 SPDX-License-Identifier: Apache-2.0 OR MIT
 
 
-General Asset Bundler Batch Tests
+Asset Bundler Batch Tests that can be run in the temp workspace.
 """
 """
 
 
 # Import builtin libraries
 # Import builtin libraries
@@ -25,10 +25,10 @@ from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture as ap_setup_fixture
 from ..ap_fixtures.asset_processor_fixture import asset_processor
 from ..ap_fixtures.asset_processor_fixture import asset_processor
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 
 
-# fmt:off
+
 from ..ap_fixtures.bundler_batch_setup_fixture \
 from ..ap_fixtures.bundler_batch_setup_fixture \
     import bundler_batch_setup_fixture as bundler_batch_helper
     import bundler_batch_setup_fixture as bundler_batch_helper
-# fmt:on
+
 from ..ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as config_backup
 from ..ap_fixtures.ap_config_backup_fixture import ap_config_backup_fixture as config_backup
 
 
 # Import LyShared
 # Import LyShared
@@ -54,7 +54,7 @@ targetProjects = ["AutomatedTesting"]
 
 
 @pytest.fixture
 @pytest.fixture
 def local_resources(request, workspace, ap_setup_fixture):
 def local_resources(request, workspace, ap_setup_fixture):
-    # Test-level asset folder. Directory contains a subfolder for each test (i.e. C1234567)
+    """ Test-level asset folder. Directory contains a sub-folder for each test (i.e. C1234567) """
     ap_setup_fixture["tests_dir"] = os.path.dirname(os.path.realpath(__file__))
     ap_setup_fixture["tests_dir"] = os.path.dirname(os.path.realpath(__file__))
 
 
 
 
@@ -67,6 +67,13 @@ class TestsAssetBundlerBatch(object):
     Asset Bundler Batch Tests for all platforms
     Asset Bundler Batch Tests for all platforms
     """
     """
 
 
+    @staticmethod
+    def ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture):
+        """Helper: Prepares the test environment; copies test files to the project in the current root, then runs AP."""
+        asset_processor.prepare_test_environment(ap_setup_fixture["tests_dir"], test_folder_name, use_current_root=True)
+        ap_result, _ = asset_processor.batch_process(platforms="pc,mac")
+        assert ap_result, "Asset Processor failed to process test assets."
+
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877174")
@@ -92,7 +99,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
-    def test_GenerateDebugInfo_DoesNotEffectOutputFile(self, workspace, bundler_batch_helper):
+    def test_GenerateDebugInfo_DoesNotEffectOutputFile(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         """
         Validates destructive overwriting for asset lists and
         Validates destructive overwriting for asset lists and
         that generating debug information does not affect asset list creation
         that generating debug information does not affect asset list creation
@@ -106,17 +113,28 @@ class TestsAssetBundlerBatch(object):
         7. Attempt to create a new asset list without debug while allowing overwrites
         7. Attempt to create a new asset list without debug while allowing overwrites
         8. Verify that file contents of the originally created asset list changed from what was stored in memory
         8. Verify that file contents of the originally created asset list changed from what was stored in memory
         """
         """
+        # Test Setup:
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
-        seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")  # Engine seed list
-        asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
+        additional_seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_1.txt")
+        # Test Setup Ends
 
 
-        # Create Asset list
+        #Create a seedlist file to use in the test.
+        helper.call_seeds(
+            seedListFile=helper["seed_list_file"],
+            addSeed=seed_asset,
+            platform="pc"
+        )
+
+        #Create an assetlist using the previously created seedlist
         helper.call_assetLists(
         helper.call_assetLists(
-            seedListFile=seed_list,
-            assetListFile=helper['asset_info_file_request'],
+            seedListFile=helper["seed_list_file"],
+            assetListFile=helper["asset_info_file_request"]
         )
         )
 
 
-        # Validate file was created
+        # Validate the assetlist file was created
         assert os.path.isfile(helper["asset_info_file_result"])
         assert os.path.isfile(helper["asset_info_file_result"])
 
 
         # Read asset list contents to compare before and after destructive overwrite
         # Read asset list contents to compare before and after destructive overwrite
@@ -125,30 +143,29 @@ class TestsAssetBundlerBatch(object):
 
 
         # Make sure destructive overwrite will fail without --allowOverwrites
         # Make sure destructive overwrite will fail without --allowOverwrites
         # Try overwriting the existing file without --allowOverwrites (should fail)
         # Try overwriting the existing file without --allowOverwrites (should fail)
-        result, _ = helper.call_assetLists(seedListFile=seed_list, addSeed=asset,
-                                           assetListFile=helper["asset_info_file_request"])
+        result, _ = helper.call_assetLists(
+            seedListFile=helper["seed_list_file"],
+            addSeed=additional_seed_asset,
+            assetListFile=helper["asset_info_file_request"]
+        )
         assert result is False, "Destructive overwrite without override DID NOT fail"
         assert result is False, "Destructive overwrite without override DID NOT fail"
 
 
         # Make sure file contents DID NOT change
         # Make sure file contents DID NOT change
-        # fmt:off
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
             assert file_contents == asset_list_file.read(), \
             assert file_contents == asset_list_file.read(), \
                 "File was changed even though the Destructive overwrite failed without override."
                 "File was changed even though the Destructive overwrite failed without override."
-        # fmt:on
 
 
         # Create the asset list file without generating debug info (and overwriting existing file)
         # Create the asset list file without generating debug info (and overwriting existing file)
         helper.call_assetLists(
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=additional_seed_asset,
             assetListFile=helper["asset_info_file_request"],
             assetListFile=helper["asset_info_file_request"],
             allowOverwrites=""
             allowOverwrites=""
         )
         )
 
 
         # Make sure file contents DID change
         # Make sure file contents DID change
-        # fmt:off
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
         with open(helper["asset_info_file_result"], "r") as asset_list_file:
             assert file_contents != asset_list_file.read(), \
             assert file_contents != asset_list_file.read(), \
                 "File was NOT changed even though the Destructive overwrite was allowed."
                 "File was NOT changed even though the Destructive overwrite was allowed."
-        # fmt:on
 
 
         # Get list of all files (relative paths) in generated asset list (no debug file created)
         # Get list of all files (relative paths) in generated asset list (no debug file created)
         assets_generated_without_debug_info = []
         assets_generated_without_debug_info = []
@@ -157,7 +174,7 @@ class TestsAssetBundlerBatch(object):
 
 
         # Create the asset list file while also generating debug info
         # Create the asset list file while also generating debug info
         helper.call_assetLists(
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=additional_seed_asset,
             allowOverwrites="",
             allowOverwrites="",
             generateDebugFile="",
             generateDebugFile="",
             assetListFile=helper["asset_info_file_request"]
             assetListFile=helper["asset_info_file_request"]
@@ -176,7 +193,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
     @pytest.mark.test_case_id("C16877177")
-    def test_BundlesAndBundleSettings_EquivalentOutput(self, workspace, bundler_batch_helper):
+    def test_BundlesAndBundleSettings_EquivalentOutput(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         """
         Validates bundle creation both through the 'bundles' and 'bundlesettings'
         Validates bundle creation both through the 'bundles' and 'bundlesettings'
         subcommands.
         subcommands.
@@ -186,31 +203,31 @@ class TestsAssetBundlerBatch(object):
         2. Create a bundle with the asset list and without a bundle settings file
         2. Create a bundle with the asset list and without a bundle settings file
         3. Create a bundle with the asset list and a bundle settings file
         3. Create a bundle with the asset list and a bundle settings file
         4. Validate calling bundle doesn't perform destructive overwrite without --allowOverwrites
         4. Validate calling bundle doesn't perform destructive overwrite without --allowOverwrites
-        5. Calling bundle again with --alowOverwrites performs destructive overwrite
+        5. Calling bundle again with --allowOverwrites performs destructive overwrite
         6. Validate contents of original bundle and overwritten bundle
         6. Validate contents of original bundle and overwritten bundle
         """
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
         seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")  # Engine seed list
         seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")  # Engine seed list
-        asset = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
 
 
         # Useful bundle locations / names (2 for comparing contents)
         # Useful bundle locations / names (2 for comparing contents)
-        # fmt:off
         platform_bundle_file_1 = os.path.join(
         platform_bundle_file_1 = os.path.join(
-            helper["test_dir"],
+            helper["project_path"],
             helper.platform_file_name(helper["bundle_file_name"], workspace.asset_processor_platform))
             helper.platform_file_name(helper["bundle_file_name"], workspace.asset_processor_platform))
 
 
-        second_bundle_file_request = os.path.join(helper["test_dir"], "bundle_2.pak")
+        second_bundle_file_request = os.path.join(helper["project_path"], "bundle_2.pak")
         platform_bundle_file_2 = os.path.join(
         platform_bundle_file_2 = os.path.join(
-            helper["test_dir"], helper.platform_file_name("bundle_2.pak", workspace.asset_processor_platform))
-        # fmt:on
+            helper["project_path"], helper.platform_file_name("bundle_2.pak", workspace.asset_processor_platform))
 
 
         # Extraction directories
         # Extraction directories
-        extract_dir_1 = os.path.join(helper["test_dir"], "ExtractDir1")
-        extract_dir_2 = os.path.join(helper["test_dir"], "ExtractDir2")
+        extract_dir_1 = os.path.join(helper["project_path"], "ExtractDir1")
+        extract_dir_2 = os.path.join(helper["project_path"], "ExtractDir2")
 
 
         # Create asset list to test bundles on
         # Create asset list to test bundles on
         helper.call_assetLists(
         helper.call_assetLists(
-            addSeed=asset,
+            addSeed=seed_asset,
             seedListFile=seed_list,
             seedListFile=seed_list,
             assetListFile=helper["asset_info_file_request"],
             assetListFile=helper["asset_info_file_request"],
         )
         )
@@ -266,8 +283,11 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
     @pytest.mark.test_case_id("C16877177")
-    def test_CreateMultiPlatformBundles_ValidContents(self, workspace, bundler_batch_helper):
+    @pytest.mark.skip(reason="https://github.com/o3de/o3de/issues/14062")
+    def test_CreateMultiPlatformBundles_ValidContents(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
         """
+        Skip reason: O3DE/O3DE#14062 and O3DE/O3DE#14060
+
         Creates bundles using the same asset list and compares that they are created equally. Also
         Creates bundles using the same asset list and compares that they are created equally. Also
         validates that platform bundles exclude/include an expected file. (excluded for WIN, included for MAC)
         validates that platform bundles exclude/include an expected file. (excluded for WIN, included for MAC)
 
 
@@ -281,45 +301,57 @@ class TestsAssetBundlerBatch(object):
         7. Verify that files were generated
         7. Verify that files were generated
         8. Verify original bundle checksums are equal to new bundle checksums
         8. Verify original bundle checksums are equal to new bundle checksums
         """
         """
+        # Test Setup Start
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
-        # fmt:off
-        assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
-            "This test requires both PC and MAC platforms to be enabled. " \
-            "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
-        # fmt:on
-
-        # Engine seed list
-        seed_list = os.path.join(workspace.paths.engine_root(), "Assets", "Engine", "SeedAssetList.seed")
-
-        # Useful bundle / asset list locations
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_assets = [os.path.join(asset_processor.project_test_cache_folder(), seed_file) for seed_file in
+                       os.listdir(asset_processor.project_test_cache_folder())]
+        asset_list = helper["asset_info_file_request"]
+        seed_list = helper["seed_list_file"]
         bundle_dir = os.path.dirname(helper["bundle_file"])
         bundle_dir = os.path.dirname(helper["bundle_file"])
         bundle_files = {}
         bundle_files = {}
         duplicate_bundle_files = {}
         duplicate_bundle_files = {}
         for platform in helper["platforms"]:
         for platform in helper["platforms"]:
             bundle_files[platform] = os.path.join(
             bundle_files[platform] = os.path.join(
-                bundle_dir,
-                helper.platform_file_name("bundle.pak", platforms[platform])
-            )
+                bundle_dir, helper.platform_file_name("bundle.pak", platforms[platform]))
             duplicate_bundle_files[platform] = os.path.join(
             duplicate_bundle_files[platform] = os.path.join(
-                bundle_dir,
-                helper.platform_file_name("duplicateBundle.pak", platforms[platform])
-            )
+                bundle_dir, helper.platform_file_name("duplicateBundle.pak", platforms[platform]))
 
 
-        duplicate_asset_info_file_request = os.path.join(helper["test_dir"], "duplicateAssetFileInfo.assetlist")
-        duplicate_bundle_file = os.path.join(helper["test_dir"], "duplicateBundle.pak")
+        duplicate_asset_info_file_request = os.path.join(
+            helper["project_path"], "duplicateAssetFileInfo.assetlist")
+        duplicate_bundle_file = os.path.join(
+            helper["project_path"], "duplicateBundle.pak")
+        # Test Setup Ends
+
+        assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
+            "This test requires both PC and MAC platforms to be enabled. " \
+            "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
 
 
-        # Create an asset list to work with
+        helper.call_seeds(
+            seedListFile=seed_list,
+            addSeed=seed_assets,
+            platform="pc,mac"
+        )
         helper.call_assetLists(
         helper.call_assetLists(
             seedListFile=seed_list,
             seedListFile=seed_list,
-            assetListFile=helper["asset_info_file_request"],
-            platform=helper["platforms_as_string"],
+            assetListFile=asset_list,
+            platform="pc",
+        )
+        helper.call_assetLists(
+            seedListFile=seed_list,
+            assetListFile=asset_list,
+            platform="mac",
         )
         )
-
-        # Create bundles for both pc and mac
         helper.call_bundles(
         helper.call_bundles(
-            assetListFile=helper["asset_info_file_request"],
+            assetListFile=asset_list,
             outputBundlePath=helper["bundle_file"],
             outputBundlePath=helper["bundle_file"],
-            platform=helper["platforms_as_string"],
+            platform="pc",
+        )
+        helper.call_bundles(
+            assetListFile=asset_list,
+            outputBundlePath=helper["bundle_file"],
+            platform="mac",
         )
         )
 
 
         # Ensure that the bundles were created
         # Ensure that the bundles were created
@@ -327,21 +359,21 @@ class TestsAssetBundlerBatch(object):
             assert os.path.isfile(bundle_file)
             assert os.path.isfile(bundle_file)
 
 
         # This asset is created both on mac and windows platform
         # This asset is created both on mac and windows platform
-        file_to_check = b"engineassets/textures/Cubemap/default_level_cubemap.tif"  # [use byte str because file is in binary]
+        file_to_check = b"asset_bundler_test_assets/txtfile_0.txt"  # [use byte str because file is in binary]
 
 
         # Extract the delta catalog file from pc archive. {file_to_check} SHOULD NOT be present for PC
         # Extract the delta catalog file from pc archive. {file_to_check} SHOULD NOT be present for PC
         file_contents = helper.extract_file_content(bundle_files["pc"], "DeltaCatalog.xml")
         file_contents = helper.extract_file_content(bundle_files["pc"], "DeltaCatalog.xml")
-        # fmt:off
+
         assert file_contents.find(file_to_check), \
         assert file_contents.find(file_to_check), \
             f"{file_to_check} was found in DeltaCatalog.xml in pc bundle file {bundle_files['pc']}"
             f"{file_to_check} was found in DeltaCatalog.xml in pc bundle file {bundle_files['pc']}"
-        # fmt:on
+
 
 
         # Extract the delta catalog file from mac archive. {file_to_check} SHOULD be present for MAC
         # Extract the delta catalog file from mac archive. {file_to_check} SHOULD be present for MAC
         file_contents = helper.extract_file_content(bundle_files["mac"], "DeltaCatalog.xml")
         file_contents = helper.extract_file_content(bundle_files["mac"], "DeltaCatalog.xml")
-        # fmt:off
+
         assert file_contents.find(file_to_check), \
         assert file_contents.find(file_to_check), \
             f"{file_to_check} was not found in DeltaCatalog.xml in darwin bundle file {bundle_files['mac']}"
             f"{file_to_check} was not found in DeltaCatalog.xml in darwin bundle file {bundle_files['mac']}"
-        # fmt:on
+
 
 
         # Gather checksums for first set of bundles
         # Gather checksums for first set of bundles
         check_sums_before = {}
         check_sums_before = {}
@@ -367,10 +399,9 @@ class TestsAssetBundlerBatch(object):
         # Make sure all files were created as expected
         # Make sure all files were created as expected
         for platform in helper["platforms"]:
         for platform in helper["platforms"]:
             assert os.path.isfile(bundle_files[platform]), f"File: {bundle_files[platform]} was not created"
             assert os.path.isfile(bundle_files[platform]), f"File: {bundle_files[platform]} was not created"
-            # fmt:off
+
             assert os.path.isfile(duplicate_bundle_files[platform]), \
             assert os.path.isfile(duplicate_bundle_files[platform]), \
                 f"File: {duplicate_bundle_files[platform]} was not created"
                 f"File: {duplicate_bundle_files[platform]} was not created"
-            # fmt:on
 
 
         # Get original bundles' contents again
         # Get original bundles' contents again
         check_sums_after = {}
         check_sums_after = {}
@@ -381,17 +412,17 @@ class TestsAssetBundlerBatch(object):
 
 
         # Make sure original bundles' contents did not change during operation
         # Make sure original bundles' contents did not change during operation
         for platform in helper["platforms"]:
         for platform in helper["platforms"]:
-            # fmt:off
+
             assert check_sums_before[platform] == check_sums_after[platform], \
             assert check_sums_before[platform] == check_sums_after[platform], \
                 f"Before and after check sum for {platform} did not match"
                 f"Before and after check sum for {platform} did not match"
             assert check_sums_before[platform] == check_sums_duplicates[platform], \
             assert check_sums_before[platform] == check_sums_duplicates[platform], \
                 f"Before and duplicated check sum for {platform} did not match"
                 f"Before and duplicated check sum for {platform} did not match"
-            # fmt:on
+
 
 
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877174")
-    def test_AddAndRemoveSeedPlatform_Success(self, workspace, bundler_batch_helper):
+    def test_AddAndRemoveSeedPlatform_Success(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
         """
         Validates that the 'seeds' subcommand can add and remove seeds and seed platforms properly.
         Validates that the 'seeds' subcommand can add and remove seeds and seed platforms properly.
         Also checks that destructive overwrites require the --allowOverwrites flag
         Also checks that destructive overwrites require the --allowOverwrites flag
@@ -414,13 +445,15 @@ class TestsAssetBundlerBatch(object):
         14. Remove seed
         14. Remove seed
         15. Validate that seed was removed from the seed list
         15. Validate that seed was removed from the seed list
         """
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
 
         # Make sure asset list file does not exist entering the test
         # Make sure asset list file does not exist entering the test
         if os.path.exists(helper["asset_info_file_request"]):
         if os.path.exists(helper["asset_info_file_request"]):
             fs.delete([helper["asset_info_file_request"]], True, True)
             fs.delete([helper["asset_info_file_request"]], True, True)
 
 
-        test_asset = r"fonts/open_sans/license.txt"
         re_pattern = re.compile(r"""field="platformFlags" value="(\d+)" """)
         re_pattern = re.compile(r"""field="platformFlags" value="(\d+)" """)
         all_lines = ""
         all_lines = ""
 
 
@@ -432,10 +465,10 @@ class TestsAssetBundlerBatch(object):
             re_match = re_pattern.search(lines)
             re_match = re_pattern.search(lines)
             assert re_match, f"PlatformFlags were not found in seed file {seed_file}"
             assert re_match, f"PlatformFlags were not found in seed file {seed_file}"
             platform_flag = int(re_match.group(1))
             platform_flag = int(re_match.group(1))
-            # fmt:off
+
             assert platform_flag == expected_platform_flag, \
             assert platform_flag == expected_platform_flag, \
                 f"Expected platform flag to be {expected_platform_flag}. Actual {platform_flag}"
                 f"Expected platform flag to be {expected_platform_flag}. Actual {platform_flag}"
-            # fmt:on
+
             return lines
             return lines
 
 
         # End check_seed_platform()
         # End check_seed_platform()
@@ -443,26 +476,25 @@ class TestsAssetBundlerBatch(object):
         # Create seed list file
         # Create seed list file
         helper.call_seeds(
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
             seedListFile=helper["seed_list_file"],
-            addSeed=test_asset,
+            addSeed=seed_asset,
             platform="pc",
             platform="pc",
         )
         )
 
 
         # Validate file exists and has proper platform flag
         # Validate file exists and has proper platform flag
         assert os.path.exists(helper["seed_list_file"]), f"seed list file was not created at {helper['seed_list_file']}"
         assert os.path.exists(helper["seed_list_file"]), f"seed list file was not created at {helper['seed_list_file']}"
-        check_seed_platform(helper["seed_list_file"], test_asset, helper["platform_values"]["pc"])
+        check_seed_platform(helper["seed_list_file"], seed_asset, helper["platform_values"]["pc"])
 
 
         # Add Mac and pc as platform for seed
         # Add Mac and pc as platform for seed
         helper.call_seeds(
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
             seedListFile=helper["seed_list_file"],
-            addSeed=test_asset,
+            addSeed=seed_asset,
             platform="pc,mac",
             platform="pc,mac",
         )
         )
 
 
         # Validate both mac and pc are activated for seed
         # Validate both mac and pc are activated for seed
-        # fmt:off
-        check_seed_platform(helper["seed_list_file"], test_asset,
+
+        check_seed_platform(helper["seed_list_file"], seed_asset,
                             helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
                             helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
-        # fmt:on
 
 
         # Remove MAC platform
         # Remove MAC platform
         helper.call_seeds(
         helper.call_seeds(
@@ -471,18 +503,17 @@ class TestsAssetBundlerBatch(object):
             platform="mac",
             platform="mac",
         )
         )
         # Validate only pc platform for seed. Save file contents to variable
         # Validate only pc platform for seed. Save file contents to variable
-        all_lines = check_seed_platform(helper["seed_list_file"], test_asset, helper["platform_values"]["pc"])
+        all_lines = check_seed_platform(helper["seed_list_file"], seed_asset, helper["platform_values"]["pc"])
 
 
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], addPlatformToSeeds="", )
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], addPlatformToSeeds="", )
 
 
         assert result is False, "Calling --addPlatformToSeeds did not fail when not specifying the --platform argument"
         assert result is False, "Calling --addPlatformToSeeds did not fail when not specifying the --platform argument"
 
 
         # Make sure the file contents did not change
         # Make sure the file contents did not change
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as asset_list_file:
         with open(helper["seed_list_file"], "r") as asset_list_file:
             assert all_lines == asset_list_file.read(), \
             assert all_lines == asset_list_file.read(), \
                 "Calling --addPlatformToSeeds without --platform failed but changed the seed file"
                 "Calling --addPlatformToSeeds without --platform failed but changed the seed file"
-        # fmt:on
 
 
         # Add MAC platform via --addPlatformToSeeds
         # Add MAC platform via --addPlatformToSeeds
         helper.call_seeds(
         helper.call_seeds(
@@ -491,10 +522,9 @@ class TestsAssetBundlerBatch(object):
             platform="mac",
             platform="mac",
         )
         )
         # Validate Mac platform was added back on. Save file contents
         # Validate Mac platform was added back on. Save file contents
-        # fmt:off
-        all_lines = check_seed_platform(helper["seed_list_file"], test_asset,
+
+        all_lines = check_seed_platform(helper["seed_list_file"], seed_asset,
                                         helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
                                         helper["platform_values"]["pc"] + helper["platform_values"]["mac"])
-        # fmt:on
 
 
         # Try to remove platform without specifying a platform to remove (should fail)
         # Try to remove platform without specifying a platform to remove (should fail)
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], removePlatformFromSeeds="", )
         result, _ = helper.call_seeds(seedListFile=helper["seed_list_file"], removePlatformFromSeeds="", )
@@ -502,25 +532,24 @@ class TestsAssetBundlerBatch(object):
         assert result is False, "Calling --removePlatformFromSeeds did not fail when not specifying the --platform argument"
         assert result is False, "Calling --removePlatformFromSeeds did not fail when not specifying the --platform argument"
 
 
         # Make sure file contents did not change
         # Make sure file contents did not change
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as asset_list_file:
         with open(helper["seed_list_file"], "r") as asset_list_file:
             assert all_lines == asset_list_file.read(), \
             assert all_lines == asset_list_file.read(), \
                 "Calling --removePlatformFromSeeds without --platform failed but changed the seed file"
                 "Calling --removePlatformFromSeeds without --platform failed but changed the seed file"
-        # fmt:on
 
 
         # Remove the seed
         # Remove the seed
         helper.call_seeds(
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
             seedListFile=helper["seed_list_file"],
-            removeSeed=test_asset,
+            removeSeed=seed_asset,
             platform="pc,mac",
             platform="pc,mac",
         )
         )
 
 
         # Validate seed was removed from file
         # Validate seed was removed from file
-        # fmt:off
+
         with open(helper["seed_list_file"], "r") as seed_list_file:
         with open(helper["seed_list_file"], "r") as seed_list_file:
-            assert test_asset not in seed_list_file.read(), \
+            assert seed_asset not in seed_list_file.read(), \
                 f"Seed was not removed from asset list file {helper['seed_list_file']}"
                 f"Seed was not removed from asset list file {helper['seed_list_file']}"
-        # fmt:on
+
 
 
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
@@ -528,10 +557,10 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877178")
     @pytest.mark.test_case_id("C16877178")
-    # fmt:off
+
     def test_ComparisonOperations_Success(self, workspace, bundler_batch_helper, ap_setup_fixture,
     def test_ComparisonOperations_Success(self, workspace, bundler_batch_helper, ap_setup_fixture,
                                                         asset_processor, timeout):
                                                         asset_processor, timeout):
-        # fmt:on
+
         """
         """
         Tests asset list comparison, both by file and by comparison type. Uses a set
         Tests asset list comparison, both by file and by comparison type. Uses a set
         of controlled test assets to compare resulting output asset lists
         of controlled test assets to compare resulting output asset lists
@@ -542,14 +571,14 @@ class TestsAssetBundlerBatch(object):
         4. Validate assetlists were created properly
         4. Validate assetlists were created properly
         5. Compare using comparison rules files and just command line arguments
         5. Compare using comparison rules files and just command line arguments
         """
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
-        env = ap_setup_fixture
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
 
 
-        # fmt:off
         assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
         assert "pc" in helper["platforms"] and "mac" in helper["platforms"], \
             "This test requires both PC and MAC platforms to be enabled. " \
             "This test requires both PC and MAC platforms to be enabled. " \
             "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
             "Please rerun with commandline option: '--bundle_platforms=pc,mac'"
-        # fmt:on
+
 
 
         # Test assets arranged in common lists: six (0-5) .txt files and .dat files
         # Test assets arranged in common lists: six (0-5) .txt files and .dat files
         even_txt = ["txtfile_0.txt", "txtfile_2.txt", "txtfile_4.txt"]
         even_txt = ["txtfile_0.txt", "txtfile_2.txt", "txtfile_4.txt"]
@@ -588,26 +617,20 @@ class TestsAssetBundlerBatch(object):
             ("combined.rules", "2,0"),
             ("combined.rules", "2,0"),
         ]
         ]
 
 
-        # Get our test assets ready and processed
-        utils.prepare_test_assets(env["tests_dir"], "C16877178", env["project_test_assets_dir"])
-        asset_processor.batch_process(timeout=timeout, fastscan=False, platforms="pc,mac")
-
-        # *** Some helper functions *** #
-
         def create_seed_file(asset_names: List[str], seed_file_name: str) -> None:
         def create_seed_file(asset_names: List[str], seed_file_name: str) -> None:
-            """Adds the [asset_names] to the seed file [seed_file_name] with their specific platform"""
+            """Helper: Adds the [asset_names] to the seed file [seed_file_name] with their specific platform"""
             for asset_file_name in asset_names:
             for asset_file_name in asset_names:
                 helper.call_seeds(
                 helper.call_seeds(
-                    seedListFile=os.path.join(helper["test_dir"], seed_file_name),
-                    addSeed=os.path.join(env["test_asset_dir_name"], asset_file_name),
+                    seedListFile=os.path.join(helper["project_path"], seed_file_name),
+                    addSeed=os.path.join(asset_processor.project_test_cache_folder(), asset_file_name),
                     platform=file_platforms[asset_file_name],
                     platform=file_platforms[asset_file_name],
                 )
                 )
 
 
         def create_asset_list_file(seed_file_name: str, asset_list_file_name: str) -> None:
         def create_asset_list_file(seed_file_name: str, asset_list_file_name: str) -> None:
-            """Simple wrapper for calling the Bundler Batch for a [seed_file_name] and [asset_list_file_name]"""
+            """Helper: Simple wrapper for calling the Bundler Batch for a [seed_file_name] and [asset_list_file_name]"""
             helper.call_assetLists(
             helper.call_assetLists(
-                assetListFile=os.path.join(helper["test_dir"], asset_list_file_name),
-                seedListFile=os.path.join(helper["test_dir"], seed_file_name),
+                assetListFile=os.path.join(helper["project_path"], asset_list_file_name),
+                seedListFile=os.path.join(helper["project_path"], seed_file_name),
                 platform="pc,mac",
                 platform="pc,mac",
             )
             )
 
 
@@ -625,7 +648,7 @@ class TestsAssetBundlerBatch(object):
         def validate_asset_list(asset_list_file: str, asset_list: List[str]) -> None:
         def validate_asset_list(asset_list_file: str, asset_list: List[str]) -> None:
             """Validates that the [asset_list_file] contains exactly the assets in [asset_list]"""
             """Validates that the [asset_list_file] contains exactly the assets in [asset_list]"""
             assets_to_find = list(asset_list)  # Make copy of list. We will be removing elements as we go
             assets_to_find = list(asset_list)  # Make copy of list. We will be removing elements as we go
-            for rel_path in helper.get_asset_relative_paths(os.path.join(helper["test_dir"], asset_list_file)):
+            for rel_path in helper.get_asset_relative_paths(os.path.join(helper["project_path"], asset_list_file)):
                 asset = os.path.split(rel_path)[1]  # Get just the asset's file name
                 asset = os.path.split(rel_path)[1]  # Get just the asset's file name
                 try:
                 try:
                     assets_to_find.remove(asset)  # Attempt to remove
                     assets_to_find.remove(asset)  # Attempt to remove
@@ -684,7 +707,7 @@ class TestsAssetBundlerBatch(object):
                         out += asset_list + ","
                         out += asset_list + ","
                     else:
                     else:
                         # Get absolute file path
                         # Get absolute file path
-                        out += os.path.join(helper["test_dir"], asset_list) + ","
+                        out += os.path.join(helper["project_path"], asset_list) + ","
                 return out[:-1]  # Trim off extra comma
                 return out[:-1]  # Trim off extra comma
 
 
             # End asset_lists_to_string()
             # End asset_lists_to_string()
@@ -703,7 +726,7 @@ class TestsAssetBundlerBatch(object):
                 if second_input_arg is not None:
                 if second_input_arg is not None:
                     cmd.append(f"--secondAssetFile={second_input_arg}")
                     cmd.append(f"--secondAssetFile={second_input_arg}")
                 if use_file:
                 if use_file:
-                    file_name = os.path.join(helper["test_dir"], rule + ".rules")
+                    file_name = os.path.join(helper["project_path"], rule + ".rules")
                     cmd.append("--comparisonRulesFile=" + file_name)
                     cmd.append("--comparisonRulesFile=" + file_name)
                 else:
                 else:
                     comp_type = [i for r, i in comparison_files if r.startswith(rule)][0]  # Get comparisonType flag
                     comp_type = [i for r, i in comparison_files if r.startswith(rule)][0]  # Get comparisonType flag
@@ -717,21 +740,21 @@ class TestsAssetBundlerBatch(object):
             # End generate_compare_command()
             # End generate_compare_command()
 
 
             def verify_asset_list_contents(expected: str, output_asset_list: str) -> None:
             def verify_asset_list_contents(expected: str, output_asset_list: str) -> None:
-                # Compare relative paths from inside 'expected' and 'output_asset_list' (last output file from cmd)
+                """Helper: Compare relative paths from inside 'expected' and 'output_asset_list' (last output file from cmd)"""
                 expected_paths = []
                 expected_paths = []
                 actual_paths = []
                 actual_paths = []
                 for rel_path in helper.get_asset_relative_paths(expected):
                 for rel_path in helper.get_asset_relative_paths(expected):
                     expected_paths.append(rel_path)
                     expected_paths.append(rel_path)
                 for rel_path in helper.get_asset_relative_paths(output_asset_list):
                 for rel_path in helper.get_asset_relative_paths(output_asset_list):
                     actual_paths.append(rel_path)
                     actual_paths.append(rel_path)
-                # fmt:off
+
                 assert sorted(expected_paths) == sorted(actual_paths), \
                 assert sorted(expected_paths) == sorted(actual_paths), \
                     "Asset list comparison did not yield expected results"
                     "Asset list comparison did not yield expected results"
-                # fmt:on
+
             # End verify_asset_list_contents()
             # End verify_asset_list_contents()
 
 
             def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_mac_output: bool) -> None:
             def run_compare_command_and_verify(platform_arg: str, expect_pc_output: bool, expect_mac_output: bool) -> None:
-
+                """Helper: Adds the platform suffixes to each expected output, builds and runs the compare commands. """
                 # Expected asset list to equal result of comparison
                 # Expected asset list to equal result of comparison
                 expected_pc_asset_list = None
                 expected_pc_asset_list = None
                 expected_mac_asset_list = None
                 expected_mac_asset_list = None
@@ -744,12 +767,12 @@ class TestsAssetBundlerBatch(object):
                 last_output_arg = output_arg.split(",")[-1]
                 last_output_arg = output_arg.split(",")[-1]
                 if expect_pc_output:
                 if expect_pc_output:
                     platform = platforms["pc"]
                     platform = platforms["pc"]
-                    expected_pc_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform))
+                    expected_pc_asset_list = os.path.join(helper["project_path"], helper.platform_file_name(expected_asset_list, platform))
                     output_pc_asset_list = helper.platform_file_name(last_output_arg, platform)
                     output_pc_asset_list = helper.platform_file_name(last_output_arg, platform)
 
 
                 if expect_mac_output:
                 if expect_mac_output:
                     platform = platforms["mac"]
                     platform = platforms["mac"]
-                    expected_mac_asset_list = os.path.join(helper["test_dir"], helper.platform_file_name(expected_asset_list, platform))
+                    expected_mac_asset_list = os.path.join(helper["project_path"], helper.platform_file_name(expected_asset_list, platform))
                     output_mac_asset_list = helper.platform_file_name(last_output_arg, platform)
                     output_mac_asset_list = helper.platform_file_name(last_output_arg, platform)
 
 
                 # Build execution command
                 # Build execution command
@@ -780,7 +803,7 @@ class TestsAssetBundlerBatch(object):
 
 
         # Create comparison (.rules) files
         # Create comparison (.rules) files
         for args in comparison_files:
         for args in comparison_files:
-            rule_file = os.path.join(helper["test_dir"], args[0])
+            rule_file = os.path.join(helper["project_path"], args[0])
             logger.info(f"Creating rule file: {rule_file}")
             logger.info(f"Creating rule file: {rule_file}")
             cmd = [
             cmd = [
                 helper["bundler_batch"],
                 helper["bundler_batch"],
@@ -871,7 +894,7 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877174")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
-    def test_AssetListCreation_OutputMatchesResult(self, workspace, bundler_batch_helper):
+    def test_AssetListCreation_OutputMatchesResult(self, workspace, bundler_batch_helper, asset_processor, ap_setup_fixture):
         """
         """
         Tests that assetlists are created equivalent to the output while being created, and
         Tests that assetlists are created equivalent to the output while being created, and
         makes sure overwriting an existing file without the --allowOverwrites fails
         makes sure overwriting an existing file without the --allowOverwrites fails
@@ -886,17 +909,18 @@ class TestsAssetBundlerBatch(object):
         7. Specifying platform but not "add" or "remove" should fail
         7. Specifying platform but not "add" or "remove" should fail
         8. Verify file Has changed
         8. Verify file Has changed
         """
         """
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
 
-        # fmt:off
         assert "pc" in helper["platforms"], \
         assert "pc" in helper["platforms"], \
             "This test requires the PC platform to be enabled. " \
             "This test requires the PC platform to be enabled. " \
             "Please rerun with commandline option: '--bundle_platforms=pc'"
             "Please rerun with commandline option: '--bundle_platforms=pc'"
-        # fmt:on
 
 
         # Assetlist result file (pc platform)
         # Assetlist result file (pc platform)
         al_file_path = os.path.join(
         al_file_path = os.path.join(
-            helper["test_dir"],
+            helper["project_path"],
             helper.platform_file_name(helper["asset_info_file_name"], platforms["pc"])
             helper.platform_file_name(helper["asset_info_file_name"], platforms["pc"])
         )
         )
         seed_files_pattern = re.compile("Loading Seed List file ( ([^)]*) )")
         seed_files_pattern = re.compile("Loading Seed List file ( ([^)]*) )")
@@ -925,7 +949,7 @@ class TestsAssetBundlerBatch(object):
         # Create a seed file
         # Create a seed file
         helper.call_seeds(
         helper.call_seeds(
             seedListFile=helper["seed_list_file"],
             seedListFile=helper["seed_list_file"],
-            addSeed=r"levels\testdependencieslevel\testdependencieslevel.spawnable",
+            addSeed=seed_asset,
             platform="pc",
             platform="pc",
         )
         )
 
 
@@ -962,10 +986,8 @@ class TestsAssetBundlerBatch(object):
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877175")
     @pytest.mark.test_case_id("C16877177")
     @pytest.mark.test_case_id("C16877177")
-    # fmt:off
-    def test_AP_BundleProcessing_BundleProcessedAtRuntime(self, workspace, bundler_batch_helper,
-                                                                        asset_processor, request):
-        # fmt:on
+    def test_AP_BundleProcessing_BundleProcessedAtRuntime(self, workspace, bundler_batch_helper, asset_processor,
+                                                          ap_setup_fixture, request):
         """
         """
         Test to make sure the AP GUI will process a newly created bundle file
         Test to make sure the AP GUI will process a newly created bundle file
 
 
@@ -977,18 +999,20 @@ class TestsAssetBundlerBatch(object):
         5. Make sure bundle now exists in cache
         5. Make sure bundle now exists in cache
         """
         """
         # Set up helpers and variables
         # Set up helpers and variables
+        test_folder_name = "asset_bundler_test_assets"
         helper = bundler_batch_helper
         helper = bundler_batch_helper
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "txtfile_0.txt")
 
 
         # Make sure file gets deleted on teardown
         # Make sure file gets deleted on teardown
         request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
         request.addfinalizer(lambda: fs.delete([bundle_result_path], True, False))
 
 
-        bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
-        level_pak = r"levels\testdependencieslevel\testdependencieslevel.spawnable"
+        bundles_folder = os.path.join(bundler_batch_helper["project_path"], "Bundles")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
         bundle_result_path = os.path.join(bundles_folder,
         bundle_result_path = os.path.join(bundles_folder,
                                           helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
                                           helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
 
 
-        bundle_cache_path = os.path.join(workspace.paths.platform_cache(),
+        bundle_cache_path = os.path.join(asset_processor.temp_project_cache(asset_platform="pc"),
                                          "Bundles",
                                          "Bundles",
                                          helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
                                          helper.platform_file_name("bundle.pak", workspace.asset_processor_platform))
 
 
@@ -1001,7 +1025,7 @@ class TestsAssetBundlerBatch(object):
 
 
         # Make asset list file (used for bundle creation)
         # Make asset list file (used for bundle creation)
         helper.call_assetLists(
         helper.call_assetLists(
-            addSeed=level_pak,
+            addSeed=seed_asset,
             assetListFile=helper["asset_info_file_request"],
             assetListFile=helper["asset_info_file_request"],
         )
         )
 
 
@@ -1009,7 +1033,7 @@ class TestsAssetBundlerBatch(object):
         result, _ = asset_processor.gui_process()
         result, _ = asset_processor.gui_process()
         assert result, "AP GUI failed"
         assert result, "AP GUI failed"
 
 
-        time.sleep(5)
+        asset_processor.wait_for_idle(timeout=5)
 
 
         # Make bundle in <project_folder>/Bundles
         # Make bundle in <project_folder>/Bundles
         helper.call_bundles(
         helper.call_bundles(
@@ -1028,35 +1052,29 @@ class TestsAssetBundlerBatch(object):
 
 
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_FilesMarkedSkip_FilesAreSkipped(self, workspace, bundler_batch_helper):
+    def test_FilesMarkedSkip_FilesAreSkipped(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         """
         Test Steps:
         Test Steps:
         1. Create an asset list with a file marked as skip
         1. Create an asset list with a file marked as skip
         2. Verify file was created
         2. Verify file was created
         3. Verify that only the expected assets are present in the created asset list
         3. Verify that only the expected assets are present in the created asset list
         """
         """
+        test_folder_name = "SeedWithDependencies"
+        self.ap_prepare_test_environment(test_folder_name, asset_processor, ap_setup_fixture)
+        seed_asset = os.path.join(asset_processor.project_test_cache_folder(), "canvas1.uicanvas")
+
         expected_assets = sorted([
         expected_assets = sorted([
-            "ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
-            "ui/textures/prefab/button_disabled.tif.streamingimage",
-            "ui/textures/prefab/tooltip_sliced.tif.streamingimage",
-            "ui/textures/prefab/button_normal.tif.streamingimage"
+            "seedwithdependencies/ama_green_01.tif.streamingimage",
+            "seedwithdependencies/ama_grey_01.tif.streamingimage",
+            "seedwithdependencies/ama_white_01.tif.streamingimage",
+            "seedwithdependencies/canvas1.uicanvas"
         ])
         ])
         # Printing these lists out can save a step in debugging if this test fails on Jenkins.
         # Printing these lists out can save a step in debugging if this test fails on Jenkins.
         logger.info(f"expected_assets: {expected_assets}")
         logger.info(f"expected_assets: {expected_assets}")
 
 
         skip_assets = sorted([
         skip_assets = sorted([
-            "ui/scripts/lyshineexamples/animation/multiplesequences.luac",
-            "ui/scripts/lyshineexamples/unloadthiscanvasbutton.luac",
-            "fonts/vera.fontfamily",
-            "fonts/vera-italic.font",
-            "fonts/vera.font",
-            "fonts/vera-bold.font",
-            "fonts/vera-bold-italic.font",
-            "fonts/vera-italic.ttf",
-            "fonts/vera.ttf",
-            "fonts/vera-bold.ttf",
-            "fonts/vera-bold-italic.ttf"
+            "seedwithdependencies/default1024.font",
+            "seedwithdependencies/default2048.font"
         ])
         ])
         logger.info(f"skip_assets: {skip_assets}")
         logger.info(f"skip_assets: {skip_assets}")
 
 
@@ -1068,7 +1086,7 @@ class TestsAssetBundlerBatch(object):
         # the files were actually skipped, and not just missing.
         # the files were actually skipped, and not just missing.
         bundler_batch_helper.call_assetLists(
         bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
             assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas"
+            addSeed=seed_asset
         )
         )
         assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
         assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
         assets_in_no_skip_list = []
         assets_in_no_skip_list = []
@@ -1081,7 +1099,7 @@ class TestsAssetBundlerBatch(object):
         # Now generate an asset info file using the skip command, and verify the skip files are not in the list.
         # Now generate an asset info file using the skip command, and verify the skip files are not in the list.
         bundler_batch_helper.call_assetLists(
         bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
             assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="ui/canvases/lyshineexamples/animation/multiplesequences.uicanvas",
+            addSeed=seed_asset,
             allowOverwrites="",
             allowOverwrites="",
             skip=','.join(skip_assets)
             skip=','.join(skip_assets)
         )
         )
@@ -1094,48 +1112,9 @@ class TestsAssetBundlerBatch(object):
         logger.info(f"assets_in_list: {assets_in_list}")
         logger.info(f"assets_in_list: {assets_in_list}")
         assert assets_in_list == expected_assets
         assert assets_in_list == expected_assets
 
 
-
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetListSkipOneOfTwoParents_SharedDependencyIsIncluded(self, workspace,
-                                                                                   bundler_batch_helper):
-        """
-        Test Steps:
-        1. Create Asset List with multiple parent assets that are skipped
-        2. Verify that Asset List was created
-        3. Verify that only the expected assets are present in the asset list
-        """
-        expected_assets = [
-            "objects/cube_lod0.azlod",
-            "objects/cube_lod0_index.azbuffer",
-            "resourcepools/defaultvertexbufferpool.pool"
-        ]
-        # Test Asset Structure:
-        #          Grandparent
-        #      /        |        \
-        #   ParentA  ParentB  ParentC
-        #      \        |        /
-        #          CommonChild
-
-        # Even if we exclude all parents besides "ParentA", we should still have "CommonChild" since it is a product dependency of "ParentA"
-        bundler_batch_helper.call_assetLists(
-            assetListFile=bundler_batch_helper['asset_info_file_request'],
-            addSeed="objects/cube_lod0.azlod",
-            skip="objects/cube_lod0_position0.azbuffer, objects/cube_lod0_tangent0.azbuffer,"
-                 "objects/cube_lod0_normal0.azbuffer, objects/cube_lod0_bitangent0.azbuffer,"
-                 "objects/cube_lod0_uv0.azbuffer"
-        )
-        assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
-        assets_in_list = []
-        for rel_path in bundler_batch_helper.get_asset_relative_paths(bundler_batch_helper["asset_info_file_result"]):
-            assets_in_list.append(rel_path)
-        assert sorted(assets_in_list) == sorted(expected_assets)
-
-    @pytest.mark.BAT
-    @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetLists_SkipRoot_ExcludesAll(self, workspace, bundler_batch_helper):
+    def test_AssetLists_SkipRoot_ExcludesAll(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         """
         Negative scenario test that skips the same file being used as the parent seed.
         Negative scenario test that skips the same file being used as the parent seed.
 
 
@@ -1143,6 +1122,9 @@ class TestsAssetBundlerBatch(object):
         1. Create an asset list that skips the root asset
         1. Create an asset list that skips the root asset
         2. Verify that asset list was not generated
         2. Verify that asset list was not generated
         """
         """
+        test_folder_name = os.path.join(workspace.project, "libs\\particles")
+        asset_processor.add_source_folder_assets(test_folder_name)
+        asset_processor.batch_process()
 
 
         result, _ = bundler_batch_helper.call_assetLists(
         result, _ = bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
             assetListFile=bundler_batch_helper['asset_info_file_request'],
@@ -1157,8 +1139,8 @@ class TestsAssetBundlerBatch(object):
 
 
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
-    # fmt:off
-    def test_AssetLists_SkipUniversalWildcard_ExcludesAll(self, workspace, bundler_batch_helper):
+
+    def test_AssetLists_SkipUniversalWildcard_ExcludesAll(self, workspace, asset_processor, ap_setup_fixture, bundler_batch_helper):
         """
         """
         Negative scenario test that uses the all wildcard when generating an asset list.
         Negative scenario test that uses the all wildcard when generating an asset list.
 
 
@@ -1166,6 +1148,9 @@ class TestsAssetBundlerBatch(object):
         1. Create an Asset List while using the universal all wildcard "*"
         1. Create an Asset List while using the universal all wildcard "*"
         2. Verify that asset list was not generated
         2. Verify that asset list was not generated
         """
         """
+        test_folder_name = os.path.join(workspace.project, "libs\\particles")
+        asset_processor.add_source_folder_assets(test_folder_name)
+        asset_processor.batch_process()
 
 
         result, _ = bundler_batch_helper.call_assetLists(
         result, _ = bundler_batch_helper.call_assetLists(
             assetListFile=bundler_batch_helper['asset_info_file_request'],
             assetListFile=bundler_batch_helper['asset_info_file_request'],
@@ -1180,7 +1165,6 @@ class TestsAssetBundlerBatch(object):
 
 
     @pytest.mark.BAT
     @pytest.mark.BAT
     @pytest.mark.assetpipeline
     @pytest.mark.assetpipeline
-    # fmt:off
     def test_Bundles_InvalidAssetList_ReportsError(self, workspace, bundler_batch_helper):
     def test_Bundles_InvalidAssetList_ReportsError(self, workspace, bundler_batch_helper):
         """
         """
         Verifies that when the bundles command is used, with an invalid asset list, the command fails and prints a useful error message.
         Verifies that when the bundles command is used, with an invalid asset list, the command fails and prints a useful error message.
@@ -1201,3 +1185,42 @@ class TestsAssetBundlerBatch(object):
             return
             return
         logger.error("AssetBundlerBatch was expected to fail when given an invalid asset list to bundle, but did not.")
         logger.error("AssetBundlerBatch was expected to fail when given an invalid asset list to bundle, but did not.")
         assert False
         assert False
+
+    @pytest.mark.BAT
+    @pytest.mark.assetpipeline
+    @pytest.mark.parametrize("bundler_batch_helper", [False], indirect=True)
+    def test_AssetListSkipOneOfTwoParents_SharedDependencyIsIncluded(self, workspace, asset_processor, bundler_batch_helper):
+        """
+        Test Steps:
+        1. Create Asset List with multiple parent assets that are skipped
+        2. Verify that Asset List was created
+        3. Verify that only the expected assets are present in the asset list
+        """
+
+        asset_processor.batch_process()
+        expected_assets = [
+            "objects/cube_lod0.azlod",
+            "objects/cube_lod0_index.azbuffer",
+            "resourcepools/defaultvertexbufferpool.pool"
+        ]
+        # Test Asset Structure:
+        #          Grandparent
+        #      /        |        \
+        #   ParentA  ParentB  ParentC
+        #      \        |        /
+        #          CommonChild
+
+        # Even if we exclude all parents besides "ParentA", we should still have "CommonChild" since it is a product dependency of "ParentA"
+        bundler_batch_helper.call_assetLists(
+            assetListFile=bundler_batch_helper['asset_info_file_request'],
+            addSeed="objects/cube_lod0.azlod",
+            skip="objects/cube_lod0_position0.azbuffer, objects/cube_lod0_tangent0.azbuffer,"
+                 "objects/cube_lod0_normal0.azbuffer, objects/cube_lod0_bitangent0.azbuffer,"
+                 "objects/cube_lod0_uv0.azbuffer"
+        )
+        assert os.path.isfile(bundler_batch_helper["asset_info_file_result"])
+        assets_in_list = []
+        for rel_path in bundler_batch_helper.get_asset_relative_paths(
+                bundler_batch_helper["asset_info_file_result"]):
+            assets_in_list.append(rel_path)
+        assert sorted(assets_in_list) == sorted(expected_assets)

+ 547 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/TestDependenciesLevel.prefab

@@ -0,0 +1,547 @@
+{
+    "ContainerEntity": {
+        "Id": "Entity_[1146574390643]",
+        "Name": "Level",
+        "Components": {
+            "Component_[10641544592923449938]": {
+                "$type": "EditorInspectorComponent",
+                "Id": 10641544592923449938
+            },
+            "Component_[12039882709170782873]": {
+                "$type": "EditorOnlyEntityComponent",
+                "Id": 12039882709170782873
+            },
+            "Component_[12265484671603697631]": {
+                "$type": "EditorPendingCompositionComponent",
+                "Id": 12265484671603697631
+            },
+            "Component_[14126657869720434043]": {
+                "$type": "EditorEntitySortComponent",
+                "Id": 14126657869720434043
+            },
+            "Component_[15230859088967841193]": {
+                "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                "Id": 15230859088967841193,
+                "Parent Entity": ""
+            },
+            "Component_[16239496886950819870]": {
+                "$type": "EditorDisabledCompositionComponent",
+                "Id": 16239496886950819870
+            },
+            "Component_[5688118765544765547]": {
+                "$type": "EditorEntityIconComponent",
+                "Id": 5688118765544765547
+            },
+            "Component_[6545738857812235305]": {
+                "$type": "SelectionComponent",
+                "Id": 6545738857812235305
+            },
+            "Component_[7247035804068349658]": {
+                "$type": "EditorPrefabComponent",
+                "Id": 7247035804068349658
+            },
+            "Component_[9307224322037797205]": {
+                "$type": "EditorLockComponent",
+                "Id": 9307224322037797205
+            },
+            "Component_[9562516168917670048]": {
+                "$type": "EditorVisibilityComponent",
+                "Id": 9562516168917670048
+            }
+        }
+    },
+    "Entities": {
+        "Entity_[1155164325235]": {
+            "Id": "Entity_[1155164325235]",
+            "Name": "Sun",
+            "Components": {
+                "Component_[10440557478882592717]": {
+                    "$type": "SelectionComponent",
+                    "Id": 10440557478882592717
+                },
+                "Component_[13620450453324765907]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 13620450453324765907
+                },
+                "Component_[2134313378593666258]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 2134313378593666258
+                },
+                "Component_[234010807770404186]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 234010807770404186
+                },
+                "Component_[2970359110423865725]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 2970359110423865725
+                },
+                "Component_[3722854130373041803]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3722854130373041803
+                },
+                "Component_[5992533738676323195]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5992533738676323195
+                },
+                "Component_[7378860763541895402]": {
+                    "$type": "AZ::Render::EditorDirectionalLightComponent",
+                    "Id": 7378860763541895402,
+                    "Controller": {
+                        "Configuration": {
+                            "Intensity": 1.0,
+                            "CameraEntityId": "",
+                            "ShadowFilterMethod": 1
+                        }
+                    }
+                },
+                "Component_[7892834440890947578]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 7892834440890947578,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            0.0,
+                            0.0,
+                            13.487043380737305
+                        ],
+                        "Rotate": [
+                            -76.13099670410156,
+                            -0.847000002861023,
+                            -15.8100004196167
+                        ]
+                    }
+                },
+                "Component_[8599729549570828259]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 8599729549570828259
+                },
+                "Component_[952797371922080273]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 952797371922080273
+                }
+            }
+        },
+        "Entity_[1159459292531]": {
+            "Id": "Entity_[1159459292531]",
+            "Name": "Ground",
+            "Components": {
+                "Component_[11701138785793981042]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11701138785793981042
+                },
+                "Component_[12260880513256986252]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 12260880513256986252
+                },
+                "Component_[13711420870643673468]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 13711420870643673468
+                },
+                "Component_[138002849734991713]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 138002849734991713
+                },
+                "Component_[16578565737331764849]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 16578565737331764849,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[16919232076966545697]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 16919232076966545697
+                },
+                "Component_[5182430712893438093]": {
+                    "$type": "EditorMaterialComponent",
+                    "Id": 5182430712893438093
+                },
+                "Component_[5675108321710651991]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 5675108321710651991,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{0CD745C0-6AA8-569A-A68A-73A3270986C4}",
+                                    "subId": 277889906
+                                },
+                                "assetHint": "objects/groudplane/groundplane_512x512m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[5681893399601237518]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5681893399601237518
+                },
+                "Component_[592692962543397545]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 592692962543397545
+                },
+                "Component_[7090012899106946164]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 7090012899106946164
+                },
+                "Component_[9410832619875640998]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 9410832619875640998
+                }
+            }
+        },
+        "Entity_[1163754259827]": {
+            "Id": "Entity_[1163754259827]",
+            "Name": "Camera",
+            "Components": {
+                "Component_[11895140916889160460]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11895140916889160460
+                },
+                "Component_[16880285896855930892]": {
+                    "$type": "{CA11DA46-29FF-4083-B5F6-E02C3A8C3A3D} EditorCameraComponent",
+                    "Id": 16880285896855930892,
+                    "Controller": {
+                        "Configuration": {
+                            "Field of View": 55.0,
+                            "EditorEntityId": 8929576024571800510
+                        }
+                    }
+                },
+                "Component_[17187464423780271193]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 17187464423780271193
+                },
+                "Component_[17495696818315413311]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 17495696818315413311
+                },
+                "Component_[18086214374043522055]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 18086214374043522055,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Translate": [
+                            -2.3000001907348633,
+                            -3.9368600845336914,
+                            1.0
+                        ],
+                        "Rotate": [
+                            -2.050307512283325,
+                            1.9552897214889526,
+                            -43.623355865478516
+                        ]
+                    }
+                },
+                "Component_[18387556550380114975]": {
+                    "$type": "SelectionComponent",
+                    "Id": 18387556550380114975
+                },
+                "Component_[2654521436129313160]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 2654521436129313160
+                },
+                "Component_[5265045084611556958]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5265045084611556958
+                },
+                "Component_[7169798125182238623]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7169798125182238623
+                },
+                "Component_[7255796294953281766]": {
+                    "$type": "GenericComponentWrapper",
+                    "Id": 7255796294953281766,
+                    "m_template": {
+                        "$type": "FlyCameraInputComponent"
+                    }
+                },
+                "Component_[8866210352157164042]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 8866210352157164042
+                },
+                "Component_[9129253381063760879]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 9129253381063760879
+                }
+            }
+        },
+        "Entity_[1168049227123]": {
+            "Id": "Entity_[1168049227123]",
+            "Name": "Grid",
+            "Components": {
+                "Component_[11443347433215807130]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 11443347433215807130
+                },
+                "Component_[11779275529534764488]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11779275529534764488
+                },
+                "Component_[14249419413039427459]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14249419413039427459
+                },
+                "Component_[15448581635946161318]": {
+                    "$type": "AZ::Render::EditorGridComponent",
+                    "Id": 15448581635946161318,
+                    "Controller": {
+                        "Configuration": {
+                            "primarySpacing": 4.0,
+                            "primaryColor": [
+                                0.501960813999176,
+                                0.501960813999176,
+                                0.501960813999176
+                            ],
+                            "secondarySpacing": 0.5,
+                            "secondaryColor": [
+                                0.250980406999588,
+                                0.250980406999588,
+                                0.250980406999588
+                            ]
+                        }
+                    }
+                },
+                "Component_[1843303322527297409]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 1843303322527297409
+                },
+                "Component_[380249072065273654]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 380249072065273654,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[7476660583684339787]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 7476660583684339787
+                },
+                "Component_[7557626501215118375]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 7557626501215118375
+                },
+                "Component_[7984048488947365511]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 7984048488947365511
+                },
+                "Component_[8118181039276487398]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 8118181039276487398
+                },
+                "Component_[9189909764215270515]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9189909764215270515
+                }
+            }
+        },
+        "Entity_[1172344194419]": {
+            "Id": "Entity_[1172344194419]",
+            "Name": "Shader Ball",
+            "Components": {
+                "Component_[10789351944715265527]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 10789351944715265527
+                },
+                "Component_[12037033284781049225]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 12037033284781049225
+                },
+                "Component_[13759153306105970079]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 13759153306105970079
+                },
+                "Component_[14135560884830586279]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14135560884830586279
+                },
+                "Component_[16247165675903986673]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 16247165675903986673
+                },
+                "Component_[18082433625958885247]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 18082433625958885247
+                },
+                "Component_[6472623349872972660]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6472623349872972660,
+                    "Parent Entity": "Entity_[1176639161715]",
+                    "Transform Data": {
+                        "Rotate": [
+                            0.0,
+                            0.10000000149011612,
+                            180.0
+                        ]
+                    }
+                },
+                "Component_[6495255223970673916]": {
+                    "$type": "AZ::Render::EditorMeshComponent",
+                    "Id": 6495255223970673916,
+                    "Controller": {
+                        "Configuration": {
+                            "ModelAsset": {
+                                "assetId": {
+                                    "guid": "{FD340C30-755C-5911-92A3-19A3F7A77931}",
+                                    "subId": 281415304
+                                },
+                                "assetHint": "objects/shaderball/shaderball_default_1m.azmodel"
+                            }
+                        }
+                    }
+                },
+                "Component_[8056625192494070973]": {
+                    "$type": "SelectionComponent",
+                    "Id": 8056625192494070973
+                },
+                "Component_[8550141614185782969]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 8550141614185782969
+                },
+                "Component_[9439770997198325425]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 9439770997198325425
+                }
+            }
+        },
+        "Entity_[1176639161715]": {
+            "Id": "Entity_[1176639161715]",
+            "Name": "Atom Default Environment",
+            "Components": {
+                "Component_[10757302973393310045]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 10757302973393310045,
+                    "Parent Entity": "Entity_[1146574390643]"
+                },
+                "Component_[14505817420424255464]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 14505817420424255464,
+                    "ComponentOrderEntryArray": [
+                        {
+                            "ComponentId": 10757302973393310045
+                        }
+                    ]
+                },
+                "Component_[14988041764659020032]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 14988041764659020032
+                },
+                "Component_[15808690248755038124]": {
+                    "$type": "SelectionComponent",
+                    "Id": 15808690248755038124
+                },
+                "Component_[15900837685796817138]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 15900837685796817138
+                },
+                "Component_[3298767348226484884]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 3298767348226484884
+                },
+                "Component_[4076975109609220594]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 4076975109609220594
+                },
+                "Component_[5679760548946028854]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 5679760548946028854
+                },
+                "Component_[5855590796136709437]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 5855590796136709437,
+                    "Child Entity Order": [
+                        "Entity_[1155164325235]",
+                        "Entity_[1180934129011]",
+                        "Entity_[1172344194419]",
+                        "Entity_[1168049227123]",
+                        "Entity_[1163754259827]",
+                        "Entity_[1159459292531]"
+                    ]
+                },
+                "Component_[9277695270015777859]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 9277695270015777859
+                }
+            }
+        },
+        "Entity_[1180934129011]": {
+            "Id": "Entity_[1180934129011]",
+            "Name": "Global Sky",
+            "Components": {
+                "Component_[11231930600558681245]": {
+                    "$type": "AZ::Render::EditorHDRiSkyboxComponent",
+                    "Id": 11231930600558681245,
+                    "Controller": {
+                        "Configuration": {
+                            "CubemapAsset": {
+                                "assetId": {
+                                    "guid": "{215E47FD-D181-5832-B1AB-91673ABF6399}",
+                                    "subId": 1000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_skyboxcm.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[11980494120202836095]": {
+                    "$type": "SelectionComponent",
+                    "Id": 11980494120202836095
+                },
+                "Component_[1428633914413949476]": {
+                    "$type": "EditorLockComponent",
+                    "Id": 1428633914413949476
+                },
+                "Component_[14936200426671614999]": {
+                    "$type": "AZ::Render::EditorImageBasedLightComponent",
+                    "Id": 14936200426671614999,
+                    "Controller": {
+                        "Configuration": {
+                            "diffuseImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 3000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_ibldiffuse.exr.streamingimage"
+                            },
+                            "specularImageAsset": {
+                                "assetId": {
+                                    "guid": "{3FD09945-D0F2-55C8-B9AF-B2FD421FE3BE}",
+                                    "subId": 2000
+                                },
+                                "assetHint": "lightingpresets/highcontrast/goegap_4k_iblglobalcm_iblspecular.exr.streamingimage"
+                            }
+                        }
+                    }
+                },
+                "Component_[14994774102579326069]": {
+                    "$type": "EditorDisabledCompositionComponent",
+                    "Id": 14994774102579326069
+                },
+                "Component_[15417479889044493340]": {
+                    "$type": "EditorPendingCompositionComponent",
+                    "Id": 15417479889044493340
+                },
+                "Component_[15826613364991382688]": {
+                    "$type": "EditorEntitySortComponent",
+                    "Id": 15826613364991382688
+                },
+                "Component_[1665003113283562343]": {
+                    "$type": "EditorOnlyEntityComponent",
+                    "Id": 1665003113283562343
+                },
+                "Component_[3704934735944502280]": {
+                    "$type": "EditorEntityIconComponent",
+                    "Id": 3704934735944502280
+                },
+                "Component_[5698542331457326479]": {
+                    "$type": "EditorVisibilityComponent",
+                    "Id": 5698542331457326479
+                },
+                "Component_[6644513399057217122]": {
+                    "$type": "{27F1E1A1-8D9D-4C3B-BD3A-AFB9762449C0} TransformComponent",
+                    "Id": 6644513399057217122,
+                    "Parent Entity": "Entity_[1176639161715]"
+                },
+                "Component_[931091830724002070]": {
+                    "$type": "EditorInspectorComponent",
+                    "Id": 931091830724002070
+                }
+            }
+        }
+    }
+}

+ 12 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/Levels/TestDependenciesLevel/tags.txt

@@ -0,0 +1,12 @@
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0
+0,0,0,0,0,0

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Green_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6b857d0dd0d349ce5366612372290a1b9b4085ffc2e235e245739a7a6c76ea11
+size 21752

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_Grey_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:418ed2ae210922737306d653cd18ae970ba72c192bbcf4e8bc9dff005f53ea0a
+size 5020

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/AMA_White_01.tif

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cd91032afab1a93327de4a4b00146340efafd1dda5a2a0b35399427bd511f127
+size 6660

+ 564 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/Canvas1.uicanvas

@@ -0,0 +1,564 @@
+<ObjectStream version="3">
+	<Class name="UiCanvasFileObject" version="2" type="{1F02632F-F113-49B1-85AD-8CD0FA78B8AA}">
+		<Class name="AZ::Entity" field="CanvasEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+			<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+				<Class name="AZ::u64" field="id" value="474928432572" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+			</Class>
+			<Class name="AZStd::string" field="Name" value="UiCanvasEntity" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+			<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+				<Class name="UiCanvasComponent" field="element" version="4" type="{50B8CF6C-B19A-4D86-AFE9-96EFB820D422}">
+					<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+						<Class name="AZ::u64" field="Id" value="15467960535682957009" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="AZ::u64" field="UniqueId" value="11774790100548863531" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="EntityId" field="RootElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="487813334460" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="unsigned int" field="LastElement" value="9" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+					<Class name="Vector2" field="CanvasSize" value="1280.0000000 720.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+					<Class name="bool" field="IsSnapEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="int" field="DrawOrder" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+					<Class name="bool" field="IsPixelAligned" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsTextPixelAligned" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="RenderToTexture" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+					<Class name="bool" field="IsPosInputSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsConsumingAllInput" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsMultiTouchSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="bool" field="IsNavigationSupported" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="float" field="NavigationThreshold" value="0.4000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="AZ::u64" field="NavigationRepeatDelay" value="300" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="AZ::u64" field="NavigationRepeatPeriod" value="150" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					<Class name="EntityId" field="FirstHoverElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="UiAnimationSystem" field="AnimSystem" version="1" type="{2592269B-EF74-4409-B29F-682DC0B45DAF}">
+						<Class name="AZStd::vector&lt;AZStd::intrusive_ptr&lt;IUiAnimSequence&gt;, allocator&gt;" field="Sequences" type="{9F8D44A9-9731-5314-885E-B958D4216073}"/>
+					</Class>
+					<Class name="AnimationData" field="AnimationData" version="1" type="{FDC58CF7-8109-48F2-8D5D-BCBAF774ABB7}">
+						<Class name="AZStd::string" field="SerializeString" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+					</Class>
+					<Class name="EntityId" field="TooltipDisplayElement" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+						<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="float" field="SnapDistance" value="10.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="float" field="SnapRotationDegrees" value="10.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+					<Class name="AZStd::vector&lt;float, allocator&gt;" field="HorizontalGuides" type="{6106BF95-5ACD-5071-8D0E-4F846C2138AD}"/>
+					<Class name="AZStd::vector&lt;float, allocator&gt;" field="VerticalGuides" type="{6106BF95-5ACD-5071-8D0E-4F846C2138AD}"/>
+					<Class name="Color" field="GuideColor" value="0.2500000 1.0000000 0.2500000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+					<Class name="bool" field="GuidesLocked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="AZStd::vector&lt;SimpleAssetReference&lt;TextureAtlasAsset&gt;, allocator&gt;" field="TextureAtlases" type="{73F8CC7B-8504-5F80-BD45-1620CD7EF9AB}"/>
+				</Class>
+			</Class>
+			<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+			<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+		</Class>
+		<Class name="AZ::Entity" field="RootSliceEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+			<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+				<Class name="AZ::u64" field="id" value="479223399868" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+			</Class>
+			<Class name="AZStd::string" field="Name" value="479223399868" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+			<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+				<Class name="SliceComponent" field="element" version="3" type="{AFD304E4-1773-47C8-855A-8B622398934F}">
+					<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+						<Class name="AZ::u64" field="Id" value="2590986407960043829" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+					</Class>
+					<Class name="AZStd::vector&lt;AZ::Entity*, allocator&gt;" field="Entities" type="{21786AF0-2606-5B9A-86EB-0892E2820E6C}">
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="487813334460" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="_root" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="8296342203764853668" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1417335033688256310" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="2955930260092508917" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="1" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}">
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="492108301756" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="0" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="496403269052" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="1" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="500698236348" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="2" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="504993203644" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="3" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+										<Class name="ChildEntityIdOrderEntry" field="element" version="1" type="{D6F3CC55-6C7C-4D64-818F-FA3378EC8DA2}">
+											<Class name="EntityId" field="ChildEntityId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+												<Class name="AZ::u64" field="id" value="509288170940" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+											</Class>
+											<Class name="AZ::u64" field="SortIndex" value="4" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="496403269052" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image2" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="6090667790069324941" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="8387065614562102859" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-158.4188843" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="-58.4188919" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="16657781940265029894" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="3" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="8899143841318558907" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_grey_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="500698236348" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image3" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="4225407189794244608" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="10653913905093048091" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="60.8829575" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="160.8829651" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="14510703990579393410" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="4" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="3027781663307535247" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_white_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="492108301756" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="Image1" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="14527494804262531044" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1653241725306964827" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="16329198947015742888" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="2" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiImageComponent" field="element" version="8" type="{BDBEFD23-DBB4-4726-A32D-4FEAC24E51F6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="7841180896507436090" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="int" field="SpriteType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="SimpleAssetReference&lt;TextureAsset&gt;" field="SpritePath" version="1" type="{6E0B1C86-F66A-5D30-BCBB-0F9EA199E4AF}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="ama_green_01.tif" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="unsigned int" field="Index" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="Asset&lt;AttachmentImageAsset&gt;" field="AttachmentImageAsset" value="id={00000000-0000-0000-0000-000000000000}:0,type={82CEA86B-E891-4969-8F35-D8017E8902C8},hint={},loadBehavior=1" version="3" type="{61538C1C-2EDA-593B-AA53-701FF7D854E7}"/>
+									<Class name="bool" field="IsRenderTargetSRGB" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="ImageType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillCenter" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="StretchSliced" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="int" field="BlendMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillType" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="FillAmount" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="FillStartAngle" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="FillCornerOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="FillEdgeOrigin" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="bool" field="FillClockwise" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="509288170940" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="StringB" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="11423924478304368427" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="3389394107544437620" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-32.7515411" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="67.2484589" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="304592595352478546" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="6" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiTextComponent" field="element" version="9" type="{5B3FB2A7-5DC4-4033-A970-001CEC85B6C4}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="1428988889681071293" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="AZStd::string" field="Text" value="String 2" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class name="bool" field="MarkupEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="SimpleAssetReference&lt;FontAsset&gt;" field="FontFileName" version="1" type="{4953F80A-F59C-5F38-9E84-AFEB8F438CC4}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="default2048.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="float" field="FontSize" value="32.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="unsigned int" field="EffectIndex" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="int" field="TextHAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="TextVAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="CharacterSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="LineSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="OverflowMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="WrapTextSetting" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="ShrinkToFit" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="MinShrinkScale" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+						<Class name="AZ::Entity" field="element" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+							<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+								<Class name="AZ::u64" field="id" value="504993203644" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+							</Class>
+							<Class name="AZStd::string" field="Name" value="StringA" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+							<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+								<Class name="EditorOnlyEntityComponent" field="element" type="{22A16F1D-6D49-422D-AAE9-91AE45B5D3E7}">
+									<Class name="EditorComponentBase" field="BaseClass1" version="1" type="{D5346BD4-7F20-444E-B370-327ACD03D4A0}">
+										<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+											<Class name="AZ::u64" field="Id" value="14981437203688256870" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+										</Class>
+									</Class>
+									<Class name="bool" field="IsEditorOnly" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+								</Class>
+								<Class name="UiTransform2dComponent" field="element" version="3" type="{2751A5A5-3291-4A4D-9FC0-9CB0EB8D1DE6}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="13998432843499002612" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="Anchors" field="Anchors" type="{65D4346C-FB16-4CB0-9BDC-1185B122C4A9}">
+										<Class name="float" field="left" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Offsets" field="Offsets" type="{F681BA9D-245C-4630-B20E-05DD752FAD57}">
+										<Class name="float" field="left" value="-50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="top" value="-77.1047211" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="right" value="50.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+										<Class name="float" field="bottom" value="22.8952770" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									</Class>
+									<Class name="Vector2" field="Pivot" value="0.5000000 0.5000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="float" field="Rotation" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="Vector2" field="Scale" value="1.0000000 1.0000000" type="{3D80F623-C85C-4741-90D0-E4E66164E6BF}"/>
+									<Class name="int" field="ScaleToDevice" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+								</Class>
+								<Class name="UiElementComponent" field="element" version="3" type="{4A97D63E-CE7A-45B6-AAE4-102DB4334688}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="14496178371394383110" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="unsigned int" field="Id" value="5" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="bool" field="IsEnabled" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsVisibleInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectableInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsSelectedInEditor" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="bool" field="IsExpandedInEditor" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="AZStd::vector&lt;ChildEntityIdOrderEntry, allocator&gt;" field="ChildEntityIdOrder" type="{0DE523D9-AEAE-5FC4-9D40-967A2E2B8A62}"/>
+								</Class>
+								<Class name="UiTextComponent" field="element" version="9" type="{5B3FB2A7-5DC4-4033-A970-001CEC85B6C4}">
+									<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+										<Class name="AZ::u64" field="Id" value="6443965789941675950" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+									</Class>
+									<Class name="AZStd::string" field="Text" value="String A" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+									<Class name="bool" field="MarkupEnabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+									<Class name="Color" field="Color" value="1.0000000 1.0000000 1.0000000 1.0000000" type="{7894072A-9050-4F0F-901B-34B1A0D29417}"/>
+									<Class name="float" field="Alpha" value="1.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="SimpleAssetReference&lt;FontAsset&gt;" field="FontFileName" version="1" type="{4953F80A-F59C-5F38-9E84-AFEB8F438CC4}">
+										<Class name="SimpleAssetReferenceBase" field="BaseClass1" version="1" type="{E16CA6C5-5C78-4AD9-8E9B-F8C1FB4D1DB8}">
+											<Class name="AZStd::string" field="AssetPath" value="default1024.font" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+										</Class>
+									</Class>
+									<Class name="float" field="FontSize" value="32.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="unsigned int" field="EffectIndex" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
+									<Class name="int" field="TextHAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="TextVAlignment" value="1" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="CharacterSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="float" field="LineSpacing" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+									<Class name="int" field="OverflowMode" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="WrapTextSetting" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="int" field="ShrinkToFit" value="0" type="{72039442-EB38-4D42-A1AD-CB68F7E0EEF6}"/>
+									<Class name="float" field="MinShrinkScale" value="0.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
+								</Class>
+							</Class>
+							<Class name="bool" field="IsDependencyReady" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						</Class>
+					</Class>
+					<Class name="AZStd::list&lt;SliceReference, allocator&gt;" field="Prefabs" type="{DAD45EB6-5853-5645-B762-3A37F8775E12}"/>
+					<Class name="bool" field="IsDynamic" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					<Class name="AZ::Entity" field="MetadataEntity" version="2" type="{75651658-8663-478D-9090-2432DFCAFA44}">
+						<Class name="EntityId" field="Id" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+							<Class name="AZ::u64" field="id" value="483518367164" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+						</Class>
+						<Class name="AZStd::string" field="Name" value="" type="{03AAAB3F-5C47-5A66-9EBC-D5FA4DB353C9}"/>
+						<Class name="AZStd::vector&lt;AZ::Component*, allocator&gt;" field="Components" type="{13D58FF9-1088-5C69-9A1F-C2A144B57B78}">
+							<Class name="SliceMetadataInfoComponent" field="element" version="2" type="{25EE4D75-8A17-4449-81F4-E561005BAABD}">
+								<Class name="AZ::Component" field="BaseClass1" type="{EDFCB2CF-F75D-43BE-B26B-F35821B29247}">
+									<Class name="AZ::u64" field="Id" value="6119851056583331912" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								</Class>
+								<Class name="AZStd::set&lt;EntityId, AZStd::less&lt;EntityId&gt;, allocator&gt;" field="AssociatedIds" type="{78E024C3-0143-53FC-B393-0675227839AF}"/>
+								<Class name="EntityId" field="ParentId" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
+									<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
+								</Class>
+								<Class name="AZStd::unordered_set&lt;EntityId, AZStd::hash&lt;EntityId&gt;, AZStd::equal_to&lt;EntityId&gt;, allocator&gt;" field="ChildrenIds" type="{6C8F8E52-AB4A-5C1F-8E56-9AC390290B94}"/>
+								<Class name="bool" field="PersistenceFlag" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+							</Class>
+						</Class>
+						<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+						<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+					</Class>
+					<Class name="DataFlagsPerEntity" field="DataFlagsForNewEntities" version="1" type="{57FE7B9E-B2AF-4F6F-9F8D-87F671E91C99}">
+						<Class name="AZStd::unordered_map&lt;EntityId, AZStd::unordered_map&lt;AddressType, unsigned char, AZStd::hash&lt;AddressType&gt;, AZStd::equal_to&lt;AddressType&gt;, allocator&gt;, AZStd::hash&lt;EntityId&gt;, AZStd::equal_to&lt;EntityId&gt;, allocator&gt;" field="EntityToDataFlags" type="{CAB9E1F5-761E-54B8-916E-E7FB597E5EDE}"/>
+					</Class>
+				</Class>
+			</Class>
+			<Class name="bool" field="IsDependencyReady" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+			<Class name="bool" field="IsRuntimeActive" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
+		</Class>
+	</Class>
+</ObjectStream>
+

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default1024.font

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ebb0258eb7bdd50e4687d589d8cd7cca0af47ddfdb26d63f53b7e930556b2864
+size 261

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/SeedWithDependencies/default2048.font

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:922a3fd98211deab4ba49bf9eacbe1e0d09e1bea435ab2a97b8240b9d78d87c5
+size 262

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab1.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_corrupted_prefab/corrupted_prefab2.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab1.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/multiple_working_prefab/working_prefab2.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_corrupted_prefab/corrupted_prefab.prefab

@@ -0,0 +1 @@
+This is a file created to act as a purposely corrupted prefab for use in test.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab/working_prefab.prefab

@@ -0,0 +1 @@
+{}

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/TestAssets/single_working_prefab_override/working_prefab.prefab

@@ -0,0 +1 @@
+{ }

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_0.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_1.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_2.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_3.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_4.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 3 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/datfile_5.dat

@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:310e481a3de7fdce8565017090acde92f32734e5d0d79945d418ee55af163acf
+size 148

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_0.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_1.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_2.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_3.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_4.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 1 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/assets/asset_bundler_test_assets/txtfile_5.txt

@@ -0,0 +1 @@
+I am a text file! this is my contents. I should be filter-able (if that's a word) by my ".txt" extension.

+ 0 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_in_editor_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_in_editor_tests.py


+ 4 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/bundle_mode_tests.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/bundle_mode_tests.py

@@ -18,10 +18,12 @@ import ly_test_tools.log.log_monitor
 
 
 from ly_test_tools.o3de.editor_test_utils import compile_test_case_name_from_request
 from ly_test_tools.o3de.editor_test_utils import compile_test_case_name_from_request
 
 
+from ..ap_fixtures.ap_setup_fixture import ap_setup_fixture
 from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
 from ..ap_fixtures.asset_processor_fixture import asset_processor as asset_processor
 from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper
 from ..ap_fixtures.bundler_batch_setup_fixture import bundler_batch_setup_fixture as bundler_batch_helper
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeout
 
 
+
 @pytest.mark.SUITE_periodic
 @pytest.mark.SUITE_periodic
 @pytest.mark.parametrize('launcher_platform', ['windows_editor'])
 @pytest.mark.parametrize('launcher_platform', ['windows_editor'])
 @pytest.mark.parametrize('project', ['AutomatedTesting'])
 @pytest.mark.parametrize('project', ['AutomatedTesting'])
@@ -30,6 +32,8 @@ from ..ap_fixtures.timeout_option_fixture import timeout_option_fixture as timeo
 class TestBundleMode(object):
 class TestBundleMode(object):
     def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
     def test_bundle_mode_with_levels_mounts_bundles_correctly(self, request, editor, level, launcher_platform,
                                                               asset_processor, workspace, bundler_batch_helper):
                                                               asset_processor, workspace, bundler_batch_helper):
+        asset_processor.add_source_folder_assets("AutomatedTesting\\Levels\\TestDependenciesLevel")
+        asset_processor.batch_process()
         level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable")
         level_pak = os.path.join("levels", level, "TestDependenciesLevel.spawnable")
         bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
         bundles_folder = os.path.join(workspace.paths.project(), "Bundles")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")
         bundle_request_path = os.path.join(bundles_folder, "bundle.pak")

+ 0 - 0
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/conftest.py → AutomatedTesting/Gem/PythonTests/assetpipeline/asset_bundler_tests/conftest.py


+ 0 - 22
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/CMakeLists.txt

@@ -244,16 +244,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
 
 
 ## Periodic Tests ##
 ## Periodic Tests ##
 
 
-    ly_add_pytest(
-        NAME APTests.AssetBundler
-        PATH ${CMAKE_CURRENT_LIST_DIR}/asset_bundler_batch_tests.py
-        TEST_SERIAL 
-        TEST_SUITE periodic
-        RUNTIME_DEPENDENCIES
-            AZ::AssetProcessor
-            AZ::AssetBundlerBatch
-    )
-
     ly_add_pytest(
     ly_add_pytest(
         NAME APTests.MissingDependency
         NAME APTests.MissingDependency
         PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
         PATH ${CMAKE_CURRENT_LIST_DIR}/missing_dependency_tests.py
@@ -263,16 +253,4 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
             AZ::AssetProcessorBatch
             AZ::AssetProcessorBatch
     )
     )
 
 
-    ly_add_pytest(
-        NAME APTests.BundleMode
-        PATH ${CMAKE_CURRENT_LIST_DIR}/bundle_mode_tests.py
-        TEST_SERIAL
-        TEST_SUITE periodic
-        RUNTIME_DEPENDENCIES
-            AZ::AssetProcessor
-            AZ::AssetBundlerBatch
-            Legacy::Editor
-            AutomatedTesting.Assets
-    )
-
 endif()
 endif()

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/asset_processor_gui_tests_2.py

@@ -319,7 +319,7 @@ class TestsAssetProcessorGUI_AllPlatforms(object):
         # Expected test asset sources and products
         # Expected test asset sources and products
         # *.assetinfo and *.fbx files are not produced in cache, and file.fbx produces file.actor in cache
         # *.assetinfo and *.fbx files are not produced in cache, and file.fbx produces file.actor in cache
         expected_test_assets = ["Jack.fbx", "Jack.fbx.assetinfo"]
         expected_test_assets = ["Jack.fbx", "Jack.fbx.assetinfo"]
-        expected_cache_assets = ["jack.actor"]
+        expected_cache_assets = ["jack.actor", "jack.assetinfo.dbg", "jack.dbgsg", "jack.dbgsg.xml", "jack.dbgsg.json"]
 
 
         # Copy test assets to project folder and verify test assets folder exists
         # Copy test assets to project folder and verify test assets folder exists
         test_assets_folder, cache_folder = asset_processor.prepare_test_environment(env["tests_dir"], "C24168802")
         test_assets_folder, cache_folder = asset_processor.prepare_test_environment(env["tests_dir"], "C24168802")

+ 1 - 1
AutomatedTesting/Gem/PythonTests/assetpipeline/asset_processor_tests/missing_dependency_tests.py

@@ -60,7 +60,7 @@ class TestsMissingDependencies_WindowsAndMac(object):
         self._missing_dep_helper = missing_dep_helper
         self._missing_dep_helper = missing_dep_helper
         self._asset_processor.create_temp_asset_root()
         self._asset_processor.create_temp_asset_root()
         self._asset_processor.add_source_folder_assets(f"AutomatedTesting\\TestAssets")
         self._asset_processor.add_source_folder_assets(f"AutomatedTesting\\TestAssets")
-        missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), "Cache",
+        missing_dep_helper.asset_db = os.path.join(asset_processor.temp_asset_root(), self._workspace.project, "Cache",
                                                    "assetdb.sqlite")
                                                    "assetdb.sqlite")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Prefabs")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Prefabs")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Materials")
         self._asset_processor.add_source_folder_assets(f"{self._workspace.project}\\Materials")

+ 2 - 2
AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/fbx_tests.py

@@ -1090,9 +1090,9 @@ class TestsFBX_AllPlatforms(object):
             f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
             f'The following assets were expected to be in, but not found in cache: {str(missing_assets)}'
 
 
         # Load the asset database.
         # Load the asset database.
-        db_path = os.path.join(asset_processor.temp_asset_root(), "Cache",
+        db_path = os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
                                "assetdb.sqlite")
                                "assetdb.sqlite")
-        cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), "Cache",
+        cache_root = os.path.dirname(os.path.join(asset_processor.temp_asset_root(), workspace.project, "Cache",
                                                   ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
                                                   ASSET_PROCESSOR_PLATFORM_MAP[workspace.asset_processor_platform]))
 
 
         if blackbox_params.scene_debug_file:
         if blackbox_params.scene_debug_file:

+ 7 - 11
AutomatedTesting/Gem/PythonTests/assetpipeline/fbx_tests/pythonassetbuildertests.py

@@ -103,11 +103,7 @@ class TestsPythonAssetProcessing_APBatch(object):
         assert result, "AP Batch failed"
         assert result, "AP Batch failed"
 
 
         # compute the cache path
         # compute the cache path
-        platform = workspace.asset_processor_platform
-        cache_folder = asset_processor.temp_asset_root()
-        if platform == 'windows':
-            platform = 'pc'
-        cache_folder = os.path.join(cache_folder, 'Cache', platform)
+        cache_folder = asset_processor.project_test_cache_folder()
 
 
         # compute the file name to the debug file
         # compute the file name to the debug file
         asset_debug_filename = os.path.join(cache_folder, debug_filename)
         asset_debug_filename = os.path.join(cache_folder, debug_filename)
@@ -119,7 +115,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedMayaDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
     def test_ProcessSceneWithMetadata_SupportedMayaDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Maya that has a few user defined properties
         # This test loads the debug output file for an FBX exported by Maya that has a few user defined properties
 
 
-        asset_dbgsg = 'userdefinedproperties/maya_with_attributes.dbgsg'
+        asset_dbgsg = 'maya_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_lod: false'), "Malformed o3de_atom_lod value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_lod: false'), "Malformed o3de_atom_lod value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
@@ -129,7 +125,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedMaxDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
     def test_ProcessSceneWithMetadata_SupportedMaxDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Max that has a few user defined properties
         # This test loads the debug output file for an FBX exported by Max that has a few user defined properties
 
 
-        asset_dbgsg = 'userdefinedproperties/max_with_attributes.dbgsg'
+        asset_dbgsg = 'max_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_phyx_lodY: 0.000000'), "Malformed o3de_phyx_lodY value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_phyx_lodY: 0.000000'), "Malformed o3de_phyx_lodY value"
@@ -140,7 +136,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_SupportedBlenderDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
     def test_ProcessSceneWithMetadata_SupportedBlenderDataTypes_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test loads the debug output file for an FBX exported by Blender that has a few user defined properties
         # This test loads the debug output file for an FBX exported by Blender that has a few user defined properties
 
 
-        asset_dbgsg = 'userdefinedproperties/blender_with_attributes.dbgsg'
+        asset_dbgsg = 'blender_with_attributes.dbgsg'
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         dbgsg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, asset_dbgsg, ap_setup_fixture)
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_atom_material: 0'), "Malformed o3de_atom_material value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_default_lod: 0.000000'), "Malformed o3de_default_lod value"
         assert self.find_user_defined_property(dbgsg_file, 'o3de_default_lod: 0.000000'), "Malformed o3de_default_lod value"
@@ -150,7 +146,7 @@ class TestsPythonAssetProcessing_APBatch(object):
     def test_ProcessSceneWithMetadata_DebugSceneManifest_Work(self, workspace, ap_setup_fixture, asset_processor):
     def test_ProcessSceneWithMetadata_DebugSceneManifest_Work(self, workspace, ap_setup_fixture, asset_processor):
         # This test detects the debug .assetinfo file in the cahce folder
         # This test detects the debug .assetinfo file in the cahce folder
 
 
-        assetinfo_dbg = 'userdefinedproperties/blender_with_attributes.assetinfo.dbg'
+        assetinfo_dbg = 'blender_with_attributes.assetinfo.dbg'
         assetinfo_dbg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, assetinfo_dbg, ap_setup_fixture)
         assetinfo_dbg_file = self.compute_udp_asset_debug_file(workspace, asset_processor, assetinfo_dbg, ap_setup_fixture)
         assert assetinfo_dbg_file, "The debug assetinfo file is missing"
         assert assetinfo_dbg_file, "The debug assetinfo file is missing"
 
 
@@ -159,8 +155,8 @@ class TestsPythonAssetProcessing_APBatch(object):
         # of a scene containing mesh nodes that have a common parent transform node
         # of a scene containing mesh nodes that have a common parent transform node
 
 
         assetinfo_dbg_list = {
         assetinfo_dbg_list = {
-            "meshgroups/blender_with_common_parent.assetinfo.dbg",
-            "meshgroups/maya_with_common_parent.assetinfo.dbg"
+            "blender_with_common_parent.assetinfo.dbg",
+            "maya_with_common_parent.assetinfo.dbg"
         }
         }
 
 
         expected_mesh_nodes = {
         expected_mesh_nodes = {

+ 1 - 1
AutomatedTesting/Gem/PythonTests/scripting/EditMenu_Default_UndoRedo.py

@@ -39,7 +39,7 @@ def EditMenu_Default_UndoRedo():
 
 
     # Preconditions
     # Preconditions
     import azlmbr.legacy.general as general
     import azlmbr.legacy.general as general
-    from editor_python_test_tools.QtPyO3DEEditor import QtPyO3DEEditor
+    from editor_python_test_tools.QtPy.QtPyO3DEEditor import QtPyO3DEEditor
 
 
     general.idle_enable(True)
     general.idle_enable(True)
 
 

+ 1 - 1
AutomatedTesting/Gem/PythonTests/scripting/NodePalette_HappyPath_ClearSelection.py

@@ -37,7 +37,7 @@ def NodePalette_HappyPath_ClearSelection():
     #Preconditions
     #Preconditions
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import Report
     import azlmbr.legacy.general as general
     import azlmbr.legacy.general as general
-    from editor_python_test_tools.QtPyO3DEEditor import QtPyO3DEEditor
+    from editor_python_test_tools.QtPy.QtPyO3DEEditor import QtPyO3DEEditor
     from consts.scripting import (NODE_STRING_TO_NUMBER)
     from consts.scripting import (NODE_STRING_TO_NUMBER)
 
 
     general.idle_enable(True)
     general.idle_enable(True)

+ 1 - 1
AutomatedTesting/Gem/PythonTests/scripting/ScriptEvent_AddRemoveMethod_UpdatesInSC.py

@@ -37,7 +37,7 @@ def ScriptEvent_AddRemoveMethod_UpdatesInSC():
     import azlmbr.paths as paths
     import azlmbr.paths as paths
     from editor_python_test_tools.utils import Report
     from editor_python_test_tools.utils import Report
     import azlmbr.legacy.general as general
     import azlmbr.legacy.general as general
-    from editor_python_test_tools.QtPyO3DEEditor import QtPyO3DEEditor
+    from editor_python_test_tools.QtPy.QtPyO3DEEditor import QtPyO3DEEditor
     from consts.asset_editor import (SCRIPT_EVENT_UI, NODE_TEST_METHOD)
     from consts.asset_editor import (SCRIPT_EVENT_UI, NODE_TEST_METHOD)
 
 
     general.idle_enable(True)
     general.idle_enable(True)

+ 2 - 2
AutomatedTesting/Gem/PythonTests/scripting/VariableManager_ExposeVarsToComponent.py

@@ -36,10 +36,10 @@ def VariableManager_ExposeVarsToComponent():
     """
     """
 
 
     # Preconditions
     # Preconditions
-    from editor_python_test_tools.QtPyO3DEEditor import QtPyO3DEEditor
+    from editor_python_test_tools.QtPy.QtPyO3DEEditor import QtPyO3DEEditor
     from editor_python_test_tools.editor_component.editor_script_canvas import ScriptCanvasComponent, VariableState
     from editor_python_test_tools.editor_component.editor_script_canvas import ScriptCanvasComponent, VariableState
     import editor_python_test_tools.editor_component.editor_component_validation as Validators
     import editor_python_test_tools.editor_component.editor_component_validation as Validators
-    from editor_python_test_tools.QtPyCommon import CheckBoxStates
+    from editor_python_test_tools.QtPy.QtPyCommon import CheckBoxStates
     import azlmbr.legacy.general as general
     import azlmbr.legacy.general as general
     from consts.scripting import (SCRIPT_CANVAS_TEST_FILE_PATH)
     from consts.scripting import (SCRIPT_CANVAS_TEST_FILE_PATH)
     from editor_python_test_tools.editor_entity_utils import EditorEntity
     from editor_python_test_tools.editor_entity_utils import EditorEntity

+ 1 - 1
AutomatedTesting/Gem/PythonTests/scripting/VariableManager_UnpinVariableType_Works.py

@@ -26,7 +26,7 @@ def VariableManager_UnpinVariableType_Works():
     """
     """
 
 
     # Preconditions
     # Preconditions
-    from editor_python_test_tools.QtPyO3DEEditor import QtPyO3DEEditor
+    from editor_python_test_tools.QtPy.QtPyO3DEEditor import QtPyO3DEEditor
     import azlmbr.legacy.general as general
     import azlmbr.legacy.general as general
     from consts.scripting import (SCRIPT_CANVAS_UI, RESTORE_DEFAULT_LAYOUT)
     from consts.scripting import (SCRIPT_CANVAS_UI, RESTORE_DEFAULT_LAYOUT)
 
 

+ 1 - 1
CMakeLists.txt

@@ -24,7 +24,7 @@ if(NOT PROJECT_NAME)
     include(cmake/CompilerSettings.cmake)
     include(cmake/CompilerSettings.cmake)
     project(O3DE
     project(O3DE
         LANGUAGES C CXX
         LANGUAGES C CXX
-        VERSION ${LY_VERSION_STRING}
+        VERSION ${O3DE_VERSION_STRING}
     )
     )
 endif()
 endif()
 
 

+ 117 - 12
Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.cpp

@@ -21,9 +21,11 @@
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTableModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserTableModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
 #include <AzToolsFramework/AssetBrowser/AssetBrowserFilterModel.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryUtils.h>
 #include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntryUtils.h>
+#include <AzToolsFramework/AssetBrowser/AssetBrowserEntityInspectorWidget.h>
 
 
 // AzQtComponents
 // AzQtComponents
 #include <AzQtComponents/Utilities/QtWindowUtilities.h>
 #include <AzQtComponents/Utilities/QtWindowUtilities.h>
+#include <AzQtComponents/Components/Widgets/AssetFolderThumbnailView.h>
 
 
 // Editor
 // Editor
 #include "AzAssetBrowser/AzAssetBrowserRequestHandler.h"
 #include "AzAssetBrowser/AzAssetBrowserRequestHandler.h"
@@ -41,6 +43,8 @@ AZ_CVAR(bool, ed_useWIPAssetBrowserDesign, false, nullptr, AZ::ConsoleFunctorFla
 //! the layout changes to accomodate its narrow state better. See AzAssetBrowserWindow::SetNarrowMode
 //! the layout changes to accomodate its narrow state better. See AzAssetBrowserWindow::SetNarrowMode
 static constexpr int s_narrowModeThreshold = 700;
 static constexpr int s_narrowModeThreshold = 700;
 
 
+using namespace AzToolsFramework::AssetBrowser;
+
 namespace AzToolsFramework
 namespace AzToolsFramework
 {
 {
     namespace AssetBrowser
     namespace AssetBrowser
@@ -154,9 +158,93 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
             m_ui->m_searchWidget, &AzAssetBrowser::SearchWidget::ClearTypeFilter);
             m_ui->m_searchWidget, &AzAssetBrowser::SearchWidget::ClearTypeFilter);
 
 
         m_ui->m_assetBrowserTableViewWidget->SetName("AssetBrowserTableView_main");
         m_ui->m_assetBrowserTableViewWidget->SetName("AssetBrowserTableView_main");
-    }
 
 
-    m_ui->m_thumbnailView->SetPreviewerFrame(m_ui->m_previewerFrame);
+        connect(
+            m_ui->m_thumbnailView,
+            &AssetBrowserThumbnailView::entryDoubleClicked,
+            this,
+            [this](const AssetBrowserEntry* entry)
+            {
+                if (!m_ui->m_assetBrowserTreeViewWidget)
+                {
+                    return;
+                }
+
+                if (!entry)
+                {
+                    return;
+                }
+
+                if (entry->GetEntryType() != AssetBrowserEntry::AssetEntryType::Folder)
+                {
+                    return;
+                }
+
+                if (!m_assetBrowserModel)
+                {
+                    return;
+                }
+
+                if (!m_filterModel.data())
+                {
+                    return;
+                }
+
+                QModelIndex indexForEntry;
+                m_assetBrowserModel->GetEntryIndex(const_cast<AssetBrowserEntry*>(entry), indexForEntry);
+
+                if (!indexForEntry.isValid())
+                {
+                    return;
+                }
+
+                auto selectionModel = m_ui->m_assetBrowserTreeViewWidget->selectionModel();
+                auto targetIndex = m_filterModel.data()->mapFromSource(indexForEntry);
+
+                selectionModel->select(targetIndex, QItemSelectionModel::ClearAndSelect);
+
+                auto targetIndexAncestor = targetIndex.parent();
+                while (targetIndexAncestor.isValid())
+                {
+                    m_ui->m_assetBrowserTreeViewWidget->expand(targetIndexAncestor);
+                    targetIndexAncestor = targetIndexAncestor.parent();
+                }
+
+                m_ui->m_assetBrowserTreeViewWidget->scrollTo(targetIndex);
+            });
+
+        connect(
+            m_ui->m_thumbnailView,
+            &AssetBrowserThumbnailView::showInFolderTriggered,
+            this,
+            [this](const AssetBrowserEntry* entry)
+            {
+                if (!entry)
+                {
+                    return;
+                }
+
+                if (!entry->GetParent())
+                {
+                    return;
+                }
+
+                m_ui->m_searchWidget->ClearStringFilter();
+
+                QModelIndex indexForEntry;
+                m_assetBrowserModel->GetEntryIndex(const_cast<AssetBrowserEntry*>(entry->GetParent()), indexForEntry);
+
+                if (!indexForEntry.isValid())
+                {
+                    return;
+                }
+
+                auto selectionModel = m_ui->m_assetBrowserTreeViewWidget->selectionModel();
+                auto targetIndex = m_filterModel.data()->mapFromSource(indexForEntry);
+
+                selectionModel->select(targetIndex, QItemSelectionModel::ClearAndSelect);
+            });
+    }
 
 
     if (!ed_useWIPAssetBrowserDesign)
     if (!ed_useWIPAssetBrowserDesign)
     {
     {
@@ -228,6 +316,15 @@ AzAssetBrowserWindow::AzAssetBrowserWindow(QWidget* parent)
             }
             }
         });
         });
 
 
+    connect(
+        m_ui->m_assetBrowserTreeViewWidget,
+        &QAbstractItemView::clicked,
+        this,
+        [this](const QModelIndex&)
+        {
+            m_ui->m_searchWidget->ClearStringFilter();
+        });
+
     connect(m_ui->m_assetBrowserTreeViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem);
     connect(m_ui->m_assetBrowserTreeViewWidget, &QAbstractItemView::doubleClicked, this, &AzAssetBrowserWindow::DoubleClickedItem);
 
 
     connect(m_ui->m_assetBrowserTreeViewWidget, &AzAssetBrowser::AssetBrowserTreeView::ClearStringFilter,
     connect(m_ui->m_assetBrowserTreeViewWidget, &AzAssetBrowser::AssetBrowserTreeView::ClearStringFilter,
@@ -316,6 +413,9 @@ void AzAssetBrowserWindow::RegisterViewClass()
     options.showInMenu = false;
     options.showInMenu = false;
     const QString name = QString("%1 (2)").arg(LyViewPane::AssetBrowser);
     const QString name = QString("%1 (2)").arg(LyViewPane::AssetBrowser);
     AzToolsFramework::RegisterViewPane<AzAssetBrowserWindow>(qPrintable(name), LyViewPane::CategoryTools, options);
     AzToolsFramework::RegisterViewPane<AzAssetBrowserWindow>(qPrintable(name), LyViewPane::CategoryTools, options);
+
+    options.preferedDockingArea = Qt::RightDockWidgetArea;
+    AzToolsFramework::RegisterViewPane<AzToolsFramework::AssetBrowser::AssetBrowserEntityInspectorWidget>(LyViewPane::AssetBrowserInspector, LyViewPane::CategoryTools, options);
 }
 }
 
 
 QObject* AzAssetBrowserWindow::createListenerForShowAssetEditorEvent(QObject* parent)
 QObject* AzAssetBrowserWindow::createListenerForShowAssetEditorEvent(QObject* parent)
@@ -338,10 +438,9 @@ void AzAssetBrowserWindow::resizeEvent(QResizeEvent* resizeEvent)
     // but the resizeEvent holds the new size of the whole widget
     // but the resizeEvent holds the new size of the whole widget
     // So we have to save the proportions somehow
     // So we have to save the proportions somehow
     const QWidget* leftLayout = m_ui->m_leftLayout;
     const QWidget* leftLayout = m_ui->m_leftLayout;
-    const QVBoxLayout* rightLayout = m_ui->m_rightLayout;
 
 
     const float oldLeftLayoutWidth = aznumeric_cast<float>(leftLayout->geometry().width());
     const float oldLeftLayoutWidth = aznumeric_cast<float>(leftLayout->geometry().width());
-    const float oldWidth = aznumeric_cast<float>(leftLayout->geometry().width() + rightLayout->geometry().width());
+    const float oldWidth = aznumeric_cast<float>(leftLayout->geometry().width());
 
 
     const float newWidth = oldLeftLayoutWidth * aznumeric_cast<float>(resizeEvent->size().width()) / oldWidth;
     const float newWidth = oldLeftLayoutWidth * aznumeric_cast<float>(resizeEvent->size().width()) / oldWidth;
 
 
@@ -489,17 +588,23 @@ void AzAssetBrowserWindow::UpdateWidgetAfterFilter()
         m_ui->m_assetBrowserTableViewWidget->setVisible(hasFilter);
         m_ui->m_assetBrowserTableViewWidget->setVisible(hasFilter);
         m_ui->m_assetBrowserTreeViewWidget->setVisible(!hasFilter);
         m_ui->m_assetBrowserTreeViewWidget->setVisible(!hasFilter);
     }
     }
-}
 
 
-void AzAssetBrowserWindow::UpdatePreview(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* selectedEntry) const
-{
-    if (selectedEntry)
+    if (hasFilter)
     {
     {
-        m_ui->m_previewerFrame->Display(selectedEntry);
+        m_ui->m_assetBrowserTreeViewWidget->selectionModel()->select(
+            m_ui->m_assetBrowserTreeViewWidget->model()->index(0, 0, {}), QItemSelectionModel::ClearAndSelect);
     }
     }
-    else
+
+    if (ed_useNewAssetBrowserTableView)
     {
     {
-        m_ui->m_previewerFrame->Clear();
+        if (hasFilter)
+        {
+            auto thumbnailWidget = m_ui->m_thumbnailView->GetThumbnailViewWidget();
+            if (thumbnailWidget)
+            {
+                thumbnailWidget->setRootIndex(thumbnailWidget->model()->index(0, 0, {}));
+            }
+        }
     }
     }
 }
 }
 
 
@@ -587,8 +692,8 @@ void AzAssetBrowserWindow::CurrentIndexChangedSlot(const QModelIndex& idx) const
     using namespace AzToolsFramework::AssetBrowser;
     using namespace AzToolsFramework::AssetBrowser;
     auto* entry = idx.data(AssetBrowserModel::Roles::EntryRole).value<const AssetBrowserEntry*>();
     auto* entry = idx.data(AssetBrowserModel::Roles::EntryRole).value<const AssetBrowserEntry*>();
 
 
-    UpdatePreview(entry);
     UpdateBreadcrumbs(entry);
     UpdateBreadcrumbs(entry);
+    AssetBrowserPreviewRequestBus::Broadcast(&AssetBrowserPreviewRequest::PreviewAsset, entry);
 }
 }
 
 
 // while its tempting to use Activated here, we don't actually want it to count as activation
 // while its tempting to use Activated here, we don't actually want it to count as activation

+ 0 - 3
Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.h

@@ -89,9 +89,6 @@ private:
     AzToolsFramework::AssetBrowser::AssetBrowserDisplayState m_assetBrowserDisplayState =
     AzToolsFramework::AssetBrowser::AssetBrowserDisplayState m_assetBrowserDisplayState =
         AzToolsFramework::AssetBrowser::AssetBrowserDisplayState::ListViewMode;
         AzToolsFramework::AssetBrowser::AssetBrowserDisplayState::ListViewMode;
 
 
-    //! Updates the asset preview panel with data about the passed entry.
-    //! Clears the panel if nullptr is passed
-    void UpdatePreview(const AzToolsFramework::AssetBrowser::AssetBrowserEntry* selectedEntry) const;
 
 
     //! Updates breadcrumbs with the selectedEntry relative path if it's a folder or with the
     //! Updates breadcrumbs with the selectedEntry relative path if it's a folder or with the
     //! relative path of the first folder parent of the passed entry.
     //! relative path of the first folder parent of the passed entry.

+ 1 - 26
Code/Editor/AzAssetBrowser/AzAssetBrowserWindow.ui

@@ -402,20 +402,6 @@
            </layout>
            </layout>
           </widget>
           </widget>
          </widget>
          </widget>
-         <widget class="QWidget" name="previewWidgetWrapper">
-          <layout class="QVBoxLayout" name="m_rightLayout">
-           <item>
-            <widget class="AzToolsFramework::AssetBrowser::PreviewerFrame" name="m_previewerFrame">
-             <property name="frameShape">
-              <enum>QFrame::StyledPanel</enum>
-             </property>
-             <property name="frameShadow">
-              <enum>QFrame::Raised</enum>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
         </widget>
         </widget>
        </item>
        </item>
       </layout>
       </layout>
@@ -431,25 +417,14 @@
    <header>AzToolsFramework/AssetBrowser/Search/SearchWidget.h</header>
    <header>AzToolsFramework/AssetBrowser/Search/SearchWidget.h</header>
    <container>1</container>
    <container>1</container>
   </customwidget>
   </customwidget>
-  <customwidget>
-   <class>AzQtComponents::TableView</class>
-   <extends>QTreeView</extends>
-   <header>AzQtComponents/Components/Widgets/TableView.h</header>
-  </customwidget>
   <customwidget>
   <customwidget>
    <class>AzToolsFramework::AssetBrowser::AssetBrowserTreeView</class>
    <class>AzToolsFramework::AssetBrowser::AssetBrowserTreeView</class>
    <extends>QTreeView</extends>
    <extends>QTreeView</extends>
    <header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h</header>
    <header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTreeView.h</header>
   </customwidget>
   </customwidget>
-  <customwidget>
-   <class>AzToolsFramework::AssetBrowser::PreviewerFrame</class>
-   <extends>QFrame</extends>
-   <header>AzToolsFramework/AssetBrowser/Previewer/PreviewerFrame.h</header>
-   <container>1</container>
-  </customwidget>
   <customwidget>
   <customwidget>
    <class>AzToolsFramework::AssetBrowser::AssetBrowserTableView</class>
    <class>AzToolsFramework::AssetBrowser::AssetBrowserTableView</class>
-   <extends>AzQtComponents::TableView</extends>
+   <extends>QTableView</extends>
    <header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.h</header>
    <header>AzToolsFramework/AssetBrowser/Views/AssetBrowserTableView.h</header>
   </customwidget>
   </customwidget>
   <customwidget>
   <customwidget>

+ 2 - 2
Code/Editor/CMakeLists.txt

@@ -128,8 +128,8 @@ ly_add_source_properties(
     SOURCES CryEdit.cpp
     SOURCES CryEdit.cpp
     PROPERTY COMPILE_DEFINITIONS 
     PROPERTY COMPILE_DEFINITIONS 
     VALUES 
     VALUES 
-        O3DE_COPYRIGHT_YEAR=${LY_VERSION_COPYRIGHT_YEAR}
-        LY_VERSION_BUILD_NUMBER=${LY_VERSION_BUILD_NUMBER}
+        O3DE_COPYRIGHT_YEAR=${O3DE_COPYRIGHT_YEAR}
+        O3DE_BUILD_VERSION=${O3DE_BUILD_VERSION}
         ${LY_PAL_TOOLS_DEFINES}
         ${LY_PAL_TOOLS_DEFINES}
 )
 )
 ly_add_source_properties(
 ly_add_source_properties(

+ 13 - 6
Code/Editor/Controls/FolderTreeCtrl.cpp

@@ -374,15 +374,22 @@ void CFolderTreeCtrl::Edit(const QString& path)
 
 
 void CFolderTreeCtrl::ShowInExplorer(const QString& path)
 void CFolderTreeCtrl::ShowInExplorer(const QString& path)
 {
 {
-    QString absolutePath = QDir::currentPath();
-
-    CTreeItem* item = GetItem(path);
-    if (item != m_rootTreeItem)
+    if (QFileInfo(path).isAbsolute())
     {
     {
-        absolutePath += QStringLiteral("/%1").arg(path);
+        AzQtComponents::ShowFileOnDesktop(path);
     }
     }
+    else
+    {
+        QString absolutePath = QDir::currentPath();
+
+        CTreeItem* item = GetItem(path);
+        if (item != m_rootTreeItem)
+        {
+            absolutePath += QStringLiteral("/%1").arg(path);
+        }
 
 
-    AzQtComponents::ShowFileOnDesktop(absolutePath);
+        AzQtComponents::ShowFileOnDesktop(absolutePath);
+    }
 }
 }
 
 
 QIcon CFolderTreeCtrl::GetItemIcon(IconType image) const
 QIcon CFolderTreeCtrl::GetItemIcon(IconType image) const

+ 2 - 14
Code/Editor/CryEdit.cpp

@@ -92,7 +92,6 @@ AZ_POP_DISABLE_WARNING
 #include "MainWindow.h"
 #include "MainWindow.h"
 
 
 #include "Core/QtEditorApplication.h"
 #include "Core/QtEditorApplication.h"
-#include "StringDlg.h"
 #include "NewLevelDialog.h"
 #include "NewLevelDialog.h"
 #include "LayoutConfigDialog.h"
 #include "LayoutConfigDialog.h"
 #include "ViewManager.h"
 #include "ViewManager.h"
@@ -853,12 +852,12 @@ namespace
 
 
 QString FormatVersion([[maybe_unused]] const SFileVersion& v)
 QString FormatVersion([[maybe_unused]] const SFileVersion& v)
 {
 {
-    if (QObject::tr("%1").arg(LY_VERSION_BUILD_NUMBER) == "0")
+    if (QObject::tr("%1").arg(O3DE_BUILD_VERSION) == "0")
     {
     {
         return QObject::tr("Development Build");
         return QObject::tr("Development Build");
     }
     }
 
 
-    return QObject::tr("Version %1").arg(LY_VERSION_BUILD_NUMBER);
+    return QObject::tr("Version %1").arg(O3DE_BUILD_VERSION);
 }
 }
 
 
 QString FormatRichTextCopyrightNotice()
 QString FormatRichTextCopyrightNotice()
@@ -2540,17 +2539,6 @@ void CCryEditApp::OnFileExportToGameNoSurfaceTexture()
     UserExportToGame(false);
     UserExportToGame(false);
 }
 }
 
 
-//////////////////////////////////////////////////////////////////////////
-void CCryEditApp::DeleteSelectedEntities([[maybe_unused]] bool includeDescendants)
-{
-    GetIEditor()->BeginUndo();
-    CUndo undo("Delete Selected Object");
-    GetIEditor()->GetObjectManager()->DeleteSelection();
-    GetIEditor()->AcceptUndo("Delete Selection");
-    GetIEditor()->SetModifiedFlag();
-    GetIEditor()->SetModifiedModule(eModifiedBrushes);
-}
-
 void CCryEditApp::OnMoveObject()
 void CCryEditApp::OnMoveObject()
 {
 {
     ////////////////////////////////////////////////////////////////////////
     ////////////////////////////////////////////////////////////////////////

+ 0 - 1
Code/Editor/CryEdit.h

@@ -203,7 +203,6 @@ public:
     void OnViewSwitchToGame();
     void OnViewSwitchToGame();
     void OnViewSwitchToGameFullScreen();
     void OnViewSwitchToGameFullScreen();
     void OnViewDeploy();
     void OnViewDeploy();
-    void DeleteSelectedEntities(bool includeDescendants);
     void OnMoveObject();
     void OnMoveObject();
     void OnRenameObj();
     void OnRenameObj();
     void OnUndo();
     void OnUndo();

+ 0 - 17
Code/Editor/Lib/Tests/test_Main.cpp

@@ -17,23 +17,6 @@
 class EditorLibTestEnvironment
 class EditorLibTestEnvironment
     : public ::UnitTest::TraceBusHook
     : public ::UnitTest::TraceBusHook
 {
 {
-public:
-    ~EditorLibTestEnvironment() override = default;
-
-protected:
-    void SetupEnvironment() override
-    {
-        ::UnitTest::TraceBusHook::SetupEnvironment();
-
-        AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
-    }
-
-    void TeardownEnvironment() override
-    {
-        AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
-
-        ::UnitTest::TraceBusHook::TeardownEnvironment();
-    }
 };
 };
 
 
 AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)
 AZTEST_EXPORT int AZ_UNIT_TEST_HOOK_NAME(int argc, char** argv)

+ 1 - 0
Code/Editor/LyViewPaneNames.h

@@ -22,6 +22,7 @@ namespace LyViewPane
     static const char* const SceneSettings = "Scene Settings (PREVIEW)";
     static const char* const SceneSettings = "Scene Settings (PREVIEW)";
     static const char* const AssetBrowser = "Asset Browser";
     static const char* const AssetBrowser = "Asset Browser";
     static const char* const AssetEditor = "Asset Editor";
     static const char* const AssetEditor = "Asset Editor";
+    static const char* const AssetBrowserInspector = "Asset Browser Inspector";
     static const char* const EntityOutliner = "Entity Outliner";
     static const char* const EntityOutliner = "Entity Outliner";
     static const char* const EntityInspector = "Entity Inspector";
     static const char* const EntityInspector = "Entity Inspector";
     static const char* const EntityInspectorPinned = "Pinned Entity Inspector";
     static const char* const EntityInspectorPinned = "Pinned Entity Inspector";

+ 0 - 1
Code/Editor/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp

@@ -78,7 +78,6 @@
 #include <Editor/DisplaySettings.h>
 #include <Editor/DisplaySettings.h>
 #include <Editor/IconManager.h>
 #include <Editor/IconManager.h>
 #include <Editor/Settings.h>
 #include <Editor/Settings.h>
-#include <Editor/StringDlg.h>
 #include <Editor/QtViewPaneManager.h>
 #include <Editor/QtViewPaneManager.h>
 #include <Editor/EditorViewportSettings.h>
 #include <Editor/EditorViewportSettings.h>
 #include <Editor/EditorViewportCamera.h>
 #include <Editor/EditorViewportCamera.h>

+ 0 - 2
Code/Editor/Plugins/ComponentEntityEditorPlugin/Tests/test_Main.cpp

@@ -18,12 +18,10 @@ class ToolsFrameworkHook
 public:
 public:
     void SetupEnvironment() override
     void SetupEnvironment() override
     {
     {
-        AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
     }
     }
 
 
     void TeardownEnvironment() override
     void TeardownEnvironment() override
     {
     {
-        AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
     }
     }
 };
 };
 
 

+ 6 - 9
Code/Editor/PythonEditorFuncs.cpp

@@ -12,6 +12,7 @@
 #include "PythonEditorFuncs.h"
 #include "PythonEditorFuncs.h"
 
 
 // Qt
 // Qt
+#include <QInputDialog>
 #include <QMessageBox>
 #include <QMessageBox>
 #include <QFileDialog>
 #include <QFileDialog>
 
 
@@ -26,7 +27,6 @@
 #include "CryEdit.h"
 #include "CryEdit.h"
 #include "GameEngine.h"
 #include "GameEngine.h"
 #include "ViewManager.h"
 #include "ViewManager.h"
-#include "StringDlg.h"
 #include "GenericSelectItemDialog.h"
 #include "GenericSelectItemDialog.h"
 #include "Objects/BaseObject.h"
 #include "Objects/BaseObject.h"
 #include "Commands/CommandManager.h"
 #include "Commands/CommandManager.h"
@@ -336,22 +336,19 @@ namespace
 
 
     AZStd::string PyEditBox(AZStd::string_view pTitle)
     AZStd::string PyEditBox(AZStd::string_view pTitle)
     {
     {
-        StringDlg stringDialog(pTitle.data());
-        if (stringDialog.exec() == QDialog::Accepted)
+        QString stringValue = QInputDialog::getText(AzToolsFramework::GetActiveWindow(), pTitle.data(), QString());
+        if (!stringValue.isEmpty())
         {
         {
-            return stringDialog.GetString().toUtf8().constData();
+            return stringValue.toUtf8().constData();
         }
         }
         return "";
         return "";
     }
     }
 
 
     AZStd::any PyEditBoxAndCheckProperty(const char* pTitle)
     AZStd::any PyEditBoxAndCheckProperty(const char* pTitle)
     {
     {
-        StringDlg stringDialog(pTitle);
-        stringDialog.SetString(QStringLiteral(""));
-        if (stringDialog.exec() == QDialog::Accepted)
+        QString stringValue = QInputDialog::getText(AzToolsFramework::GetActiveWindow(), pTitle, QString());
+        if (!stringValue.isEmpty())
         {
         {
-            const QString stringValue = stringDialog.GetString();
-
             // detect data type
             // detect data type
             QString tempString = stringValue;
             QString tempString = stringValue;
             int countComa = 0;
             int countComa = 0;

+ 0 - 3
Code/Editor/main.cpp

@@ -20,8 +20,6 @@ int main(int argc, char* argv[])
     using CryEditMain = int (*)(int, char*[]);
     using CryEditMain = int (*)(int, char*[]);
     constexpr const char CryEditMainName[] = "CryEditMain";
     constexpr const char CryEditMainName[] = "CryEditMain";
 
 
-    AZ::AllocatorInstance<AZ::OSAllocator>::Create();
-
     auto handle = AZ::DynamicModuleHandle::Create("EditorLib");
     auto handle = AZ::DynamicModuleHandle::Create("EditorLib");
     [[maybe_unused]] const bool loaded = handle->Load(true);
     [[maybe_unused]] const bool loaded = handle->Load(true);
     AZ_Assert(loaded, "EditorLib could not be loaded");
     AZ_Assert(loaded, "EditorLib could not be loaded");
@@ -33,6 +31,5 @@ int main(int argc, char* argv[])
     }
     }
 
 
     handle = {};
     handle = {};
-    AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
     return ret;
     return ret;
 }
 }

+ 0 - 4
Code/Framework/AtomCore/Tests/InstanceDatabase.cpp

@@ -123,8 +123,6 @@ namespace UnitTest
         void SetUp() override
         void SetUp() override
         {
         {
             LeakDetectionFixture::SetUp();
             LeakDetectionFixture::SetUp();
-            AllocatorInstance<PoolAllocator>::Create();
-            AllocatorInstance<ThreadPoolAllocator>::Create();
 
 
             // create the asset database
             // create the asset database
             {
             {
@@ -155,8 +153,6 @@ namespace UnitTest
 
 
             InstanceDatabase<TestInstanceA>::Destroy();
             InstanceDatabase<TestInstanceA>::Destroy();
 
 
-            AllocatorInstance<ThreadPoolAllocator>::Destroy();
-            AllocatorInstance<PoolAllocator>::Destroy();
             LeakDetectionFixture::TearDown();
             LeakDetectionFixture::TearDown();
         }
         }
     };
     };

+ 0 - 4
Code/Framework/AtomCore/Tests/Main.cpp

@@ -44,16 +44,12 @@ class TestEnvironmentHook
 public:
 public:
     void SetupEnvironment() override
     void SetupEnvironment() override
     {
     {
-        AllocatorInstance<OSAllocator>::Create(); // used by the bus
-
         BusConnect();
         BusConnect();
     }
     }
 
 
     void TeardownEnvironment() override
     void TeardownEnvironment() override
     {
     {
         BusDisconnect();
         BusDisconnect();
-
-        AllocatorInstance<OSAllocator>::Destroy(); // used by the bus
     }
     }
 };
 };
 
 

+ 0 - 2
Code/Framework/AzCore/AzCore/AzCoreModule.cpp

@@ -13,7 +13,6 @@
 #include <AzCore/IO/Streamer/StreamerComponent.h>
 #include <AzCore/IO/Streamer/StreamerComponent.h>
 #include <AzCore/Jobs/JobManagerComponent.h>
 #include <AzCore/Jobs/JobManagerComponent.h>
 #include <AzCore/Serialization/Json/JsonSystemComponent.h>
 #include <AzCore/Serialization/Json/JsonSystemComponent.h>
-#include <AzCore/Memory/MemoryComponent.h>
 #include <AzCore/Script/ScriptSystemComponent.h>
 #include <AzCore/Script/ScriptSystemComponent.h>
 #include <AzCore/Slice/SliceComponent.h>
 #include <AzCore/Slice/SliceComponent.h>
 #include <AzCore/Slice/SliceSystemComponent.h>
 #include <AzCore/Slice/SliceSystemComponent.h>
@@ -30,7 +29,6 @@ namespace AZ
         : AZ::Module()
         : AZ::Module()
     {
     {
         m_descriptors.insert(m_descriptors.end(), {
         m_descriptors.insert(m_descriptors.end(), {
-            MemoryComponent::CreateDescriptor(),
             StreamerComponent::CreateDescriptor(),
             StreamerComponent::CreateDescriptor(),
             JobManagerComponent::CreateDescriptor(),
             JobManagerComponent::CreateDescriptor(),
             JsonSystemComponent::CreateDescriptor(),
             JsonSystemComponent::CreateDescriptor(),

+ 13 - 69
Code/Framework/AzCore/AzCore/Component/ComponentApplication.cpp

@@ -415,8 +415,8 @@ namespace AZ
         m_descriptor.m_recordingMode = AllocatorManager::Instance().GetDefaultTrackingMode();
         m_descriptor.m_recordingMode = AllocatorManager::Instance().GetDefaultTrackingMode();
 
 
         // Initializes the OSAllocator and SystemAllocator as soon as possible
         // Initializes the OSAllocator and SystemAllocator as soon as possible
-        CreateOSAllocator();
-        CreateSystemAllocator();
+        AZ::Debug::Trace::Instance().Init();
+        ConfigureSystemAllocatorTracking();
 
 
         // Now that the Allocators are initialized, the Command Line parameters can be parsed
         // Now that the Allocators are initialized, the Command Line parameters can be parsed
         m_commandLine.Parse(m_argC, m_argV);
         m_commandLine.Parse(m_argC, m_argV);
@@ -515,7 +515,7 @@ namespace AZ
         m_entityActivatedEvent.DisconnectAllHandlers();
         m_entityActivatedEvent.DisconnectAllHandlers();
         m_entityDeactivatedEvent.DisconnectAllHandlers();
         m_entityDeactivatedEvent.DisconnectAllHandlers();
 
 
-        DestroyAllocator();
+        AZ::Debug::Trace::Instance().Destroy();
     }
     }
 
 
     void ComponentApplication::InitializeSettingsRegistry()
     void ComponentApplication::InitializeSettingsRegistry()
@@ -741,10 +741,7 @@ namespace AZ
 
 
         m_descriptor = descriptor;
         m_descriptor = descriptor;
 
 
-        // Re-invokes CreateOSAllocator and CreateSystemAllocator function to allow the component application
-        // to use supplied startupParameters and descriptor parameters this time
-        CreateOSAllocator();
-        CreateSystemAllocator();
+        ConfigureSystemAllocatorTracking();
 
 
 #if !defined(_RELEASE)
 #if !defined(_RELEASE)
         m_budgetTracker.Init();
         m_budgetTracker.Init();
@@ -911,73 +908,20 @@ namespace AZ
 #endif // defined(AZ_ENABLE_DEBUG_TOOLS)
 #endif // defined(AZ_ENABLE_DEBUG_TOOLS)
     }
     }
 
 
-    void ComponentApplication::DestroyAllocator()
-    {
-        AZ::Debug::Trace::Instance().Destroy();
-
-        // kill the system allocator if we created it
-        if (m_isSystemAllocatorOwner)
-        {
-            AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
-
-            m_isSystemAllocatorOwner = false;
-        }
-
-        if (m_isOSAllocatorOwner)
-        {
-            AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
-            m_isOSAllocatorOwner = false;
-        }
-
-        m_osAllocator = nullptr;
-    }
-
-    void ComponentApplication::CreateOSAllocator()
-    {
-        if (!m_startupParameters.m_allocator)
-        {
-            if (!AZ::AllocatorInstance<AZ::OSAllocator>::IsReady())
-            {
-                AZ::AllocatorInstance<AZ::OSAllocator>::Create();
-                m_isOSAllocatorOwner = true;
-            }
-            m_osAllocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
-        }
-        else
-        {
-            m_osAllocator = m_startupParameters.m_allocator;
-        }
-    }
-
     //=========================================================================
     //=========================================================================
-    // CreateSystemAllocator
+    // ConfigureSystemAllocatorTracking
     // [5/30/2012]
     // [5/30/2012]
     //=========================================================================
     //=========================================================================
-    void ComponentApplication::CreateSystemAllocator()
+    void ComponentApplication::ConfigureSystemAllocatorTracking()
     {
     {
-        AZ::Debug::Trace::Instance().Init();
-
-        if (m_descriptor.m_useExistingAllocator || AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady())
+        AZ::Debug::AllocationRecords* records = AllocatorInstance<SystemAllocator>::Get().GetRecords();
+        if (records)
         {
         {
-            AZ_Assert(AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady(), "You must setup AZ::SystemAllocator instance, before you can call Create application with m_useExistingAllocator flag set to true");
-            return;
-        }
-        else
-        {
-            // Create the system allocator
-            AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
-
-            AZ::Debug::AllocationRecords* records = AllocatorInstance<SystemAllocator>::Get().GetRecords();
-            if (records)
-            {
-                records->SetMode(m_descriptor.m_recordingMode);
-                records->SetSaveNames(m_descriptor.m_allocationRecordsSaveNames);
-                records->SetDecodeImmediately(m_descriptor.m_allocationRecordsAttemptDecodeImmediately);
-                records->AutoIntegrityCheck(m_descriptor.m_autoIntegrityCheck);
-                records->MarkUallocatedMemory(m_descriptor.m_markUnallocatedMemory);
-            }
-
-            m_isSystemAllocatorOwner = true;
+            records->SetMode(m_descriptor.m_recordingMode);
+            records->SetSaveNames(m_descriptor.m_allocationRecordsSaveNames);
+            records->SetDecodeImmediately(m_descriptor.m_allocationRecordsAttemptDecodeImmediately);
+            records->AutoIntegrityCheck(m_descriptor.m_autoIntegrityCheck);
+            records->MarkUallocatedMemory(m_descriptor.m_markUnallocatedMemory);
         }
         }
     }
     }
 
 

+ 2 - 12
Code/Framework/AzCore/AzCore/Component/ComponentApplication.h

@@ -149,10 +149,6 @@ namespace AZ
         {
         {
             StartupParameters() {}
             StartupParameters() {}
 
 
-            //! If set, this allocator is used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap.
-            //! If it's left nullptr (default), the \ref OSAllocator will be used.
-            IAllocator* m_allocator = nullptr;
-
             //! Callback to create AZ::Modules for the static libraries linked by this application.
             //! Callback to create AZ::Modules for the static libraries linked by this application.
             //! Leave null if the application uses no static AZ::Modules.
             //! Leave null if the application uses no static AZ::Modules.
             //! \note Dynamic AZ::Modules are specified in the ComponentApplication::Descriptor.
             //! \note Dynamic AZ::Modules are specified in the ComponentApplication::Descriptor.
@@ -187,7 +183,6 @@ namespace AZ
          */
          */
         virtual Entity* Create(const Descriptor& descriptor, const StartupParameters& startupParameters = StartupParameters());
         virtual Entity* Create(const Descriptor& descriptor, const StartupParameters& startupParameters = StartupParameters());
         virtual void Destroy();
         virtual void Destroy();
-        virtual void DestroyAllocator(); // Called at the end of Destroy(). Applications can override to do tear down work right before allocator is destroyed.
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////
         // ComponentApplicationRequests
         // ComponentApplicationRequests
@@ -313,11 +308,8 @@ namespace AZ
         /// Common logic shared between the multiple Create(...) functions.
         /// Common logic shared between the multiple Create(...) functions.
         void        CreateCommon();
         void        CreateCommon();
 
 
-        /// Create the operating system allocator if not supplied in the StartupParameters
-        void        CreateOSAllocator();
-
-        /// Create the system allocator using the data in the m_descriptor
-        void        CreateSystemAllocator();
+        /// Create the system allocator to track allocations
+        void        ConfigureSystemAllocatorTracking();
 
 
         virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
         virtual void MergeSettingsToRegistry(SettingsRegistryInterface& registry);
 
 
@@ -369,8 +361,6 @@ namespace AZ
         EntityRemovedEvent                          m_entityDeactivatedEvent;
         EntityRemovedEvent                          m_entityDeactivatedEvent;
         Descriptor                                  m_descriptor;
         Descriptor                                  m_descriptor;
         bool                                        m_isStarted{ false };
         bool                                        m_isStarted{ false };
-        bool                                        m_isSystemAllocatorOwner{ false };
-        bool                                        m_isOSAllocatorOwner{ false };
         IAllocator*                                 m_osAllocator{ nullptr };
         IAllocator*                                 m_osAllocator{ nullptr };
         EntitySetType                               m_entities;
         EntitySetType                               m_entities;
 
 

+ 9 - 6
Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.cpp

@@ -33,10 +33,11 @@ namespace AZ::ComponentApplicationLifecycle
                 " or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
                 " or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
             return false;
             return false;
         }
         }
-        auto eventRegistrationKey = FixedValueString::format("%.*s/%.*s", AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey),
+        // The Settings Registry key used to signal the event is a transient runtime key which is separate from the registration key
+        auto eventSignalKey = FixedValueString::format("%.*s/%.*s", AZ_STRING_ARG(ApplicationLifecycleEventSignalKey),
             AZ_STRING_ARG(eventName));
             AZ_STRING_ARG(eventName));
 
 
-        return settingsRegistry.MergeSettings(eventValue, Format::JsonMergePatch, eventRegistrationKey);
+        return settingsRegistry.MergeSettings(eventValue, Format::JsonMergePatch, eventSignalKey);
     }
     }
 
 
     bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName)
     bool RegisterEvent(AZ::SettingsRegistryInterface& settingsRegistry, AZStd::string_view eventName)
@@ -74,12 +75,14 @@ namespace AZ::ComponentApplicationLifecycle
                 " or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
                 " or in *.setreg within the project", AZ_STRING_ARG(eventName), AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey));
             return false;
             return false;
         }
         }
-        auto eventNameRegistrationKey = FixedValueString::format("%.*s/%.*s", AZ_STRING_ARG(ApplicationLifecycleEventRegistrationKey),
-            AZ_STRING_ARG(eventName));
-        auto lifecycleCallback = [callback = AZStd::move(callback), eventNameRegistrationKey](
+
+        // The signal key is used for invoking the handler
+        auto lifecycleCallback = [callback = AZStd::move(callback),
+            eventNameSignalKey = FixedValueString::format("%.*s/%.*s",
+                AZ_STRING_ARG(ApplicationLifecycleEventSignalKey), AZ_STRING_ARG(eventName))](
             const AZ::SettingsRegistryInterface::NotifyEventArgs& notifyEventArgs)
             const AZ::SettingsRegistryInterface::NotifyEventArgs& notifyEventArgs)
         {
         {
-            if (notifyEventArgs.m_jsonKeyPath == eventNameRegistrationKey)
+            if (notifyEventArgs.m_jsonKeyPath == eventNameSignalKey)
             {
             {
                 callback(notifyEventArgs);
                 callback(notifyEventArgs);
             }
             }

+ 7 - 1
Code/Framework/AzCore/AzCore/Component/ComponentApplicationLifecycle.h

@@ -13,9 +13,15 @@
 
 
 namespace AZ::ComponentApplicationLifecycle
 namespace AZ::ComponentApplicationLifecycle
 {
 {
-    //! Root Key where lifecycle events should be registered under
+    //! Root Key used to determine where lifecycle events are registered underneath
     inline constexpr AZStd::string_view ApplicationLifecycleEventRegistrationKey = "/O3DE/Application/LifecycleEvents";
     inline constexpr AZStd::string_view ApplicationLifecycleEventRegistrationKey = "/O3DE/Application/LifecycleEvents";
 
 
+    //! Root Key to use for signaling lifecycle events
+    //! This key section is runtime only and will not be merged into the aggregated setreg file
+    //! produced by the SettingsRegistryBuilder
+    //! It is used to separately from the registration key section, to avoid the scenario
+    //! where registering a lifecycle event would result in signaling the event.
+    inline constexpr AZStd::string_view ApplicationLifecycleEventSignalKey = "/O3DE/Runtime/Application/LifecycleEvents";
 
 
     //! Validates that the event @eventName is stored in the array at ApplicationLifecycleEventRegistrationKey
     //! Validates that the event @eventName is stored in the array at ApplicationLifecycleEventRegistrationKey
     //! @param settingsRegistry registry where @eventName will be searched
     //! @param settingsRegistry registry where @eventName will be searched

+ 9 - 3
Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.cpp

@@ -18,8 +18,14 @@
 
 
 namespace AZ::Debug
 namespace AZ::Debug
 {
 {
-    PerformanceCollector::PerformanceCollector(const AZStd::string_view logCategory, AZStd::span<const AZStd::string_view> m_metricNames, OnBatchCompleteCallback onBatchCompleteCallback)
-        : m_logCategory(logCategory), m_onBatchCompleteCallback(onBatchCompleteCallback)
+    PerformanceCollector::PerformanceCollector(
+        const AZStd::string_view logCategory,
+        AZStd::span<const AZStd::string_view> m_metricNames,
+        OnBatchCompleteCallback onBatchCompleteCallback,
+        const AZStd::string_view fileExtension)
+        : m_logCategory(logCategory)
+        , m_onBatchCompleteCallback(onBatchCompleteCallback)
+        , m_fileExtension(fileExtension)
     {
     {
         for (const auto& metricName : m_metricNames)
         for (const auto& metricName : m_metricNames)
         {
         {
@@ -244,7 +250,7 @@ namespace AZ::Debug
             settingsRegistry->Get(m_outputFilePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath);
             settingsRegistry->Get(m_outputFilePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_ProjectUserPath);
             AZ::Date::Iso8601TimestampString utcTimestamp;
             AZ::Date::Iso8601TimestampString utcTimestamp;
             AZ::Date::GetFilenameCompatibleFormatNowWithMicroseconds(utcTimestamp);
             AZ::Date::GetFilenameCompatibleFormatNowWithMicroseconds(utcTimestamp);
-            m_outputFilePath /= AZStd::string::format("Performance_%s_%s.json", m_logCategory.c_str(), utcTimestamp.c_str());
+            m_outputFilePath /= AZStd::string::format("Performance_%s_%s.%s", m_logCategory.c_str(), utcTimestamp.c_str(), m_fileExtension.c_str());
 
 
             constexpr AZ::IO::OpenMode openMode = AZ::IO::OpenMode::ModeWrite;
             constexpr AZ::IO::OpenMode openMode = AZ::IO::OpenMode::ModeWrite;
             auto stream = AZStd::make_unique<AZ::IO::SystemFileStream>(m_outputFilePath.c_str(), openMode);
             auto stream = AZStd::make_unique<AZ::IO::SystemFileStream>(m_outputFilePath.c_str(), openMode);

+ 11 - 3
Code/Framework/AzCore/AzCore/Debug/PerformanceCollector.h

@@ -44,7 +44,12 @@ namespace AZ::Debug
         //!                    Each output file will be named Performance_<Category>_<CreationTime>.json
         //!                    Each output file will be named Performance_<Category>_<CreationTime>.json
         //! @param m_metricNames List of all the metrics that will be recorded. All metrics will be measured in Microseconds.
         //! @param m_metricNames List of all the metrics that will be recorded. All metrics will be measured in Microseconds.
         //! @param onBatchCompleteCallback See comments above in OnBatchCompleteCallback declaration.
         //! @param onBatchCompleteCallback See comments above in OnBatchCompleteCallback declaration.
-        PerformanceCollector(const AZStd::string_view logCategory, AZStd::span<const AZStd::string_view> m_metricNames, OnBatchCompleteCallback onBatchCompleteCallback);
+        //! @param m_fileExtension The extension of the output file, to appear after "." Defaults to "json".
+        PerformanceCollector(
+            const AZStd::string_view logCategory,
+            AZStd::span<const AZStd::string_view> m_metricNames,
+            OnBatchCompleteCallback onBatchCompleteCallback,
+            const AZStd::string_view fileExtension = "json");
         ~PerformanceCollector() = default;
         ~PerformanceCollector() = default;
 
 
         static constexpr char LogName[] = "PerformanceCollector";
         static constexpr char LogName[] = "PerformanceCollector";
@@ -94,9 +99,11 @@ namespace AZ::Debug
         //! and performance capture for as many batches.
         //! and performance capture for as many batches.
         void UpdateNumberOfCaptureBatches(AZ::u32 newValue);
         void UpdateNumberOfCaptureBatches(AZ::u32 newValue);
 
 
-        const AZ::IO::Path& GetOutputFilePath() { return m_outputFilePath;  }
+        const AZ::IO::Path& GetOutputFilePath() const { return m_outputFilePath;  }
 
 
-        const AZStd::string& GetOutputDataBuffer() { return m_outputDataBuffer; }
+        const AZStd::string& GetOutputDataBuffer() const { return m_outputDataBuffer; }
+
+        const AZStd::string& GetFileExtension() const { return m_fileExtension; }
 
 
     private:
     private:
         //! A helper function that loops across all statistics in @m_statisticsManager
         //! A helper function that loops across all statistics in @m_statisticsManager
@@ -118,6 +125,7 @@ namespace AZ::Debug
         AZStd::chrono::steady_clock::time_point m_startWaitTime;
         AZStd::chrono::steady_clock::time_point m_startWaitTime;
         bool m_isWaitingBeforeNextBatch = true;
         bool m_isWaitingBeforeNextBatch = true;
         OnBatchCompleteCallback m_onBatchCompleteCallback; // A notification will be sent each time a batch of frames is performance collected.
         OnBatchCompleteCallback m_onBatchCompleteCallback; // A notification will be sent each time a batch of frames is performance collected.
+        AZStd::string m_fileExtension = "json";
 
 
         //! Only used when @m_captureType == CaptureType::LogStatistics.
         //! Only used when @m_captureType == CaptureType::LogStatistics.
         AZ::Statistics::StatisticsManager<AZStd::string> m_statisticsManager;
         AZ::Statistics::StatisticsManager<AZStd::string> m_statisticsManager;

+ 0 - 1
Code/Framework/AzCore/AzCore/Jobs/JobManagerComponent.cpp

@@ -115,7 +115,6 @@ namespace AZ
     //=========================================================================
     //=========================================================================
     void JobManagerComponent::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
     void JobManagerComponent::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
     {
     {
-        dependent.push_back(AZ_CRC("MemoryService", 0x5c4d473c));
         dependent.push_back(AZ_CRC("ProfilerService", 0x505033c9));
         dependent.push_back(AZ_CRC("ProfilerService", 0x505033c9));
     }
     }
 
 

+ 4 - 5
Code/Framework/AzCore/AzCore/Memory/AllocationRecords.cpp

@@ -369,21 +369,20 @@ namespace AZ::Debug
             return;
             return;
         }
         }
 
 
-        Debug::AllocationInfo* ai{};
-        const bool addressAlreadyRecorded = [this, address, newAddress, &ai]
+        const auto [addressAlreadyRecorded, ai] = [this, address, newAddress]() -> std::pair<bool, Debug::AllocationInfo*>
         {
         {
             AZStd::scoped_lock lock(m_recordsMutex);
             AZStd::scoped_lock lock(m_recordsMutex);
             auto node = m_records.extract(address);
             auto node = m_records.extract(address);
             if (node.empty())
             if (node.empty())
             {
             {
-                return false;
+                return {false, nullptr};
             }
             }
 
 
             // Make a best effort to avoid reallocations from mutating the
             // Make a best effort to avoid reallocations from mutating the
             // records map when recording a reallocation
             // records map when recording a reallocation
             node.key() = newAddress;
             node.key() = newAddress;
-            ai = &m_records.insert(AZStd::move(node)).position->second;
-            return true;
+            auto ai = &m_records.insert(AZStd::move(node)).position->second;
+            return {true, ai};
         }();
         }();
         if (!addressAlreadyRecorded)
         if (!addressAlreadyRecorded)
         {
         {

+ 2 - 1
Code/Framework/AzCore/AzCore/Memory/AllocatorBase.h

@@ -31,7 +31,8 @@ namespace AZ
         //---------------------------------------------------------------------
         //---------------------------------------------------------------------
         // IAllocator implementation
         // IAllocator implementation
         //---------------------------------------------------------------------
         //---------------------------------------------------------------------
-        const Debug::AllocationRecords* GetRecords() const final;
+        using IAllocator::GetRecords;
+        const Debug::AllocationRecords* GetRecords() const override;
         void SetRecords(Debug::AllocationRecords* records) final;
         void SetRecords(Debug::AllocationRecords* records) final;
         bool IsReady() const final;
         bool IsReady() const final;
         void PostCreate() override;
         void PostCreate() override;

+ 0 - 37
Code/Framework/AzCore/AzCore/Memory/AllocatorInstance.h

@@ -49,20 +49,6 @@ namespace AZ::AllocatorStorage
             static AllocatorEnvironmentVariable s_allocator;
             static AllocatorEnvironmentVariable s_allocator;
             return *s_allocator;
             return *s_allocator;
         }
         }
-
-        static void Create()
-        {
-            GetAllocator();
-        }
-
-        static void Destroy()
-        {
-        }
-
-        AZ_FORCE_INLINE static bool IsReady()
-        {
-            return true;
-        }
     };
     };
 } // namespace AZ::AllocatorStorage
 } // namespace AZ::AllocatorStorage
 
 
@@ -75,33 +61,10 @@ namespace AZ::Internal
     class AllocatorInstanceBase
     class AllocatorInstanceBase
     {
     {
     public:
     public:
-        // Maintained for backwards compatibility, prefer to use Get() instead.
-        // Get was previously used to get the the schema, however, that bypasses what the allocators are doing.
-        // If the schema is needed, call Get().GetSchema()
-        AZ_FORCE_INLINE static IAllocator& GetAllocator()
-        {
-            return StoragePolicy::GetAllocator();
-        }
-
         AZ_FORCE_INLINE static IAllocator& Get()
         AZ_FORCE_INLINE static IAllocator& Get()
         {
         {
             return StoragePolicy::GetAllocator();
             return StoragePolicy::GetAllocator();
         }
         }
-
-        static void Create()
-        {
-            StoragePolicy::Create();
-        }
-
-        static void Destroy()
-        {
-            StoragePolicy::Destroy();
-        }
-
-        AZ_FORCE_INLINE static bool IsReady()
-        {
-            return StoragePolicy::IsReady();
-        }
     };
     };
 } // namespace AZ::Internal
 } // namespace AZ::Internal
 
 

+ 0 - 131
Code/Framework/AzCore/AzCore/Memory/MemoryComponent.cpp

@@ -1,131 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-
-#include <AzCore/Memory/MemoryComponent.h>
-#include <AzCore/Math/Crc.h>
-
-#include <AzCore/Memory/PoolAllocator.h>
-
-#include <AzCore/Serialization/SerializeContext.h>
-#include <AzCore/Serialization/EditContext.h>
-
-namespace AZ
-{
-    //=========================================================================
-    // MemoryComponent
-    // [5/29/2012]
-    //=========================================================================
-    MemoryComponent::MemoryComponent()
-    {
-        m_isPoolAllocator = true;
-        m_isThreadPoolAllocator = true;
-
-        m_createdPoolAllocator = false;
-        m_createdThreadPoolAllocator = false;
-    }
-
-    //=========================================================================
-    // ~MemoryComponent
-    // [5/29/2012]
-    //=========================================================================
-    MemoryComponent::~MemoryComponent()
-    {
-        // Normally we will just call destroy destroy in the deactivate function
-        // and create in activate. But memory component is special that
-        // it must be operational after Init so all parts of the engine can be operational.
-        // This is why we must check the destructor (which is symmetrical to Init() anyway)
-        if (m_createdThreadPoolAllocator && AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::IsReady())
-        {
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
-        }
-        if (m_createdPoolAllocator && AZ::AllocatorInstance<AZ::PoolAllocator>::IsReady())
-        {
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
-        }
-    }
-
-    //=========================================================================
-    // Init
-    // [5/29/2012]
-    //=========================================================================
-    void MemoryComponent::Init()
-    {
-        // IMPORTANT: The SystemAllocator is already operational
-
-        // TODO: add the setting to the serialization layer
-        if (m_isPoolAllocator)
-        {
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Create();
-            m_createdPoolAllocator = true;
-        }
-        if (m_isThreadPoolAllocator)
-        {
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
-            m_createdThreadPoolAllocator = true;
-        }
-    }
-
-    //=========================================================================
-    // Activate
-    // [5/29/2012]
-    //=========================================================================
-    void MemoryComponent::Activate()
-    {
-    }
-
-    //=========================================================================
-    // Deactivate
-    // [5/29/2012]
-    //=========================================================================
-    void MemoryComponent::Deactivate()
-    {
-    }
-
-    //=========================================================================
-    // GetProvidedServices
-    //=========================================================================
-    void MemoryComponent::GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided)
-    {
-        provided.push_back(AZ_CRC("MemoryService", 0x5c4d473c));
-    }
-
-    //=========================================================================
-    // GetIncompatibleServices
-    //=========================================================================
-    void MemoryComponent::GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible)
-    {
-        incompatible.push_back(AZ_CRC("MemoryService", 0x5c4d473c));
-    }
-
-    //=========================================================================
-    // Reflect
-    //=========================================================================
-    void MemoryComponent::Reflect(ReflectContext* context)
-    {
-        if (SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context))
-        {
-            serializeContext->Class<MemoryComponent, AZ::Component>()
-                ->Version(1)
-                ->Field("isPoolAllocator", &MemoryComponent::m_isPoolAllocator)
-                ->Field("isThreadPoolAllocator", &MemoryComponent::m_isThreadPoolAllocator)
-                ;
-
-            ;
-            if (EditContext* editContext = serializeContext->GetEditContext())
-            {
-                editContext->Class<MemoryComponent>("Memory System", "Initializes and maintains fundamental memory allocators")
-                    ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
-                        ->Attribute(AZ::Edit::Attributes::Category, "Engine")
-                        ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC("System", 0xc94d118b))
-                    ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MemoryComponent::m_isPoolAllocator, "Pool allocator", "Fast allocation pooling for small allocations < 256 bytes, use from main thread only!")
-                    ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MemoryComponent::m_isThreadPoolAllocator, "Thread pool allocator", "Fast allocation pool that can be used from any thread, if uses more memory! (as it keeps the pools per thread)")
-                    ;
-            }
-        }
-    }
-} // namespace AZ

+ 0 - 58
Code/Framework/AzCore/AzCore/Memory/MemoryComponent.h

@@ -1,58 +0,0 @@
-/*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
-#ifndef AZCORE_MEMORY_COMPONENT_H
-#define AZCORE_MEMORY_COMPONENT_H
-
-#include <AzCore/Component/Component.h>
-#include <AzCore/Math/Crc.h>
-
-namespace AZ
-{
-    /**
-     * Memory manager component. It will manager all memory managers.
-     * This is the only component that requires special care as memory managers
-     * must be operational for any system to operate. In addition this component doesn't have a factory
-     * as it's managed by the bootstrap component class.
-     */
-    class MemoryComponent
-        : public Component
-    {
-    public:
-        AZ_COMPONENT(AZ::MemoryComponent, "{6F450DDA-6F4D-40fd-A93B-E5CCCDBC72AB}")
-
-        MemoryComponent();
-        virtual ~MemoryComponent();
-
-        //////////////////////////////////////////////////////////////////////////
-        // Component base
-        void Init() override;
-        void Activate() override;
-        void Deactivate() override;
-        //////////////////////////////////////////////////////////////////////////
-
-    private:
-
-        /// \ref ComponentDescriptor::GetProvidedServices
-        static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
-        /// \ref ComponentDescriptor::GetIncompatibleServices
-        static void GetIncompatibleServices(ComponentDescriptor::DependencyArrayType& incompatible);
-        /// \ref ComponentDescriptor::Reflect
-        static void Reflect(ReflectContext* reflection);
-
-        // serialized data
-        bool m_isPoolAllocator;
-        bool m_isThreadPoolAllocator;
-
-        // non-serialized data
-        bool m_createdPoolAllocator;
-        bool m_createdThreadPoolAllocator;
-    };
-}
-
-#endif // AZCORE_MEMORY_COMPONENT_H
-#pragma once

+ 5 - 9
Code/Framework/AzCore/AzCore/Serialization/SerializeContext.cpp

@@ -3169,18 +3169,14 @@ namespace AZ
         auto genericClassInfoContainer = AZStd::move(m_moduleLocalGenericClassInfos);
         auto genericClassInfoContainer = AZStd::move(m_moduleLocalGenericClassInfos);
         auto serializeContextSet = AZStd::move(m_serializeContextSet);
         auto serializeContextSet = AZStd::move(m_serializeContextSet);
         // Un-reflect GenericClassInfo from each serialize context registered with the module
         // Un-reflect GenericClassInfo from each serialize context registered with the module
-        // The SerailizeContext uses the SystemAllocator so it is required to be ready in order to remove the data
-        if (AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady())
+        for (AZ::SerializeContext* serializeContext : serializeContextSet)
         {
         {
-            for (AZ::SerializeContext* serializeContext : serializeContextSet)
+            for (const auto& [specializedTypeId, genericClassInfo] : genericClassInfoContainer)
             {
             {
-                for (const auto& [specializedTypeId, genericClassInfo] : genericClassInfoContainer)
-                {
-                    serializeContext->RemoveGenericClassInfo(genericClassInfo);
-                }
-
-                serializeContext->m_perModuleSet.erase(this);
+                serializeContext->RemoveGenericClassInfo(genericClassInfo);
             }
             }
+
+            serializeContext->m_perModuleSet.erase(this);
         }
         }
 
 
         // Cleanup the memory for the GenericClassInfo objects.
         // Cleanup the memory for the GenericClassInfo objects.

+ 0 - 19
Code/Framework/AzCore/AzCore/UnitTest/TestTypes.h

@@ -166,25 +166,6 @@ namespace UnitTest
     class ScopedAllocatorBenchmarkEnvironment
     class ScopedAllocatorBenchmarkEnvironment
         : public AZ::Test::BenchmarkEnvironmentBase
         : public AZ::Test::BenchmarkEnvironmentBase
     {
     {
-    public:
-        ScopedAllocatorBenchmarkEnvironment()
-        {
-            // Only create the allocator if it doesn't exist
-            if (!AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady())
-            {
-                AZ::AllocatorInstance<AZ::SystemAllocator>::Create();
-                m_ownsAllocator = true;
-            }
-        }
-        ~ScopedAllocatorBenchmarkEnvironment() override
-        {
-            if (m_ownsAllocator)
-            {
-                AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
-            }
-        }
-    private:
-        bool m_ownsAllocator{};
     };
     };
 #endif
 #endif
 
 

+ 0 - 6
Code/Framework/AzCore/AzCore/UserSettings/UserSettingsComponent.cpp

@@ -86,12 +86,6 @@ namespace AZ
         provided.push_back(AZ_CRC("UserSettingsService", 0xa0eadff5));
         provided.push_back(AZ_CRC("UserSettingsService", 0xa0eadff5));
     }
     }
 
 
-    //-----------------------------------------------------------------------------
-    void UserSettingsComponent::GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent)
-    {
-        dependent.push_back(AZ_CRC("MemoryService", 0x5c4d473c));
-    }
-
     //-----------------------------------------------------------------------------
     //-----------------------------------------------------------------------------
 
 
     //-----------------------------------------------------------------------------
     //-----------------------------------------------------------------------------

+ 0 - 2
Code/Framework/AzCore/AzCore/UserSettings/UserSettingsComponent.h

@@ -57,8 +57,6 @@ namespace AZ
 
 
         /// \ref ComponentDescriptor::GetProvidedServices
         /// \ref ComponentDescriptor::GetProvidedServices
         static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
         static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
-        /// \ref ComponentDescriptor::GetDependentServices
-        static void GetDependentServices(ComponentDescriptor::DependencyArrayType& dependent);
         /// \red ComponentDescriptor::Reflect
         /// \red ComponentDescriptor::Reflect
         static void Reflect(ReflectContext* reflection);
         static void Reflect(ReflectContext* reflection);
 
 

+ 0 - 2
Code/Framework/AzCore/AzCore/azcore_files.cmake

@@ -412,8 +412,6 @@ set(FILES
     Memory/IAllocator.h
     Memory/IAllocator.h
     Memory/Memory.cpp
     Memory/Memory.cpp
     Memory/Memory.h
     Memory/Memory.h
-    Memory/MemoryComponent.cpp
-    Memory/MemoryComponent.h
     Memory/nedmalloc.inl
     Memory/nedmalloc.inl
     Memory/NewAndDelete.inl
     Memory/NewAndDelete.inl
     Memory/OSAllocator.cpp
     Memory/OSAllocator.cpp

+ 0 - 6
Code/Framework/AzCore/Tests/AZStd/VariantSerialization.cpp

@@ -25,9 +25,6 @@ namespace UnitTest
         {
         {
             LeakDetectionFixture::SetUp();
             LeakDetectionFixture::SetUp();
 
 
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Create();
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
-
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             m_serializeContext = AZStd::make_unique<AZ::SerializeContext>();
             AZ::Entity::Reflect(m_serializeContext.get());
             AZ::Entity::Reflect(m_serializeContext.get());
             
             
@@ -41,9 +38,6 @@ namespace UnitTest
 
 
             m_serializeContext.reset();
             m_serializeContext.reset();
 
 
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
-
             LeakDetectionFixture::TearDown();
             LeakDetectionFixture::TearDown();
         }
         }
 
 

+ 0 - 12
Code/Framework/AzCore/Tests/AssetJsonSerializerTests.cpp

@@ -72,9 +72,6 @@ namespace JsonSerializationTests
         {
         {
             BaseJsonSerializerFixture::SetUp();
             BaseJsonSerializerFixture::SetUp();
 
 
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Create();
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
-
             // Set up the Job Manager with 1 thread so that the Asset Manager is able to load assets.
             // Set up the Job Manager with 1 thread so that the Asset Manager is able to load assets.
             AZ::JobManagerDesc jobDesc;
             AZ::JobManagerDesc jobDesc;
             AZ::JobManagerThreadDesc threadDesc;
             AZ::JobManagerThreadDesc threadDesc;
@@ -104,9 +101,6 @@ namespace JsonSerializationTests
             delete m_jobContext;
             delete m_jobContext;
             delete m_jobManager;
             delete m_jobManager;
 
 
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
-
             BaseJsonSerializerFixture::TearDown();
             BaseJsonSerializerFixture::TearDown();
         }
         }
 
 
@@ -157,9 +151,6 @@ namespace JsonSerializationTests
 
 
         void SetUp() override
         void SetUp() override
         {
         {
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Create();
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Create();
-
             // Set up the Job Manager with 1 thread so that the Asset Manager is able to load assets.
             // Set up the Job Manager with 1 thread so that the Asset Manager is able to load assets.
             AZ::JobManagerDesc jobDesc;
             AZ::JobManagerDesc jobDesc;
             AZ::JobManagerThreadDesc threadDesc;
             AZ::JobManagerThreadDesc threadDesc;
@@ -181,9 +172,6 @@ namespace JsonSerializationTests
             AZ::JobContext::SetGlobalContext(nullptr);
             AZ::JobContext::SetGlobalContext(nullptr);
             delete m_jobContext;
             delete m_jobContext;
             delete m_jobManager;
             delete m_jobManager;
-
-            AZ::AllocatorInstance<AZ::ThreadPoolAllocator>::Destroy();
-            AZ::AllocatorInstance<AZ::PoolAllocator>::Destroy();
         }
         }
 
 
         using JsonSerializerConformityTestDescriptor<AZ::Data::Asset<TestAssetData>>::Reflect;
         using JsonSerializerConformityTestDescriptor<AZ::Data::Asset<TestAssetData>>::Reflect;

+ 3 - 14
Code/Framework/AzCore/Tests/Components.cpp

@@ -18,7 +18,6 @@
 #include <AzCore/IO/Streamer/StreamerComponent.h>
 #include <AzCore/IO/Streamer/StreamerComponent.h>
 #include <AzCore/Serialization/ObjectStream.h>
 #include <AzCore/Serialization/ObjectStream.h>
 
 
-#include <AzCore/Memory/MemoryComponent.h>
 #include <AzCore/UserSettings/UserSettingsComponent.h>
 #include <AzCore/UserSettings/UserSettingsComponent.h>
 #include <AzCore/IO/SystemFile.h>
 #include <AzCore/IO/SystemFile.h>
 
 
@@ -60,7 +59,6 @@ namespace UnitTest
         appDesc.m_recordingMode = AllocationRecords::RECORD_FULL;
         appDesc.m_recordingMode = AllocationRecords::RECORD_FULL;
         Entity* systemEntity = app.Create(appDesc);
         Entity* systemEntity = app.Create(appDesc);
 
 
-        systemEntity->CreateComponent<MemoryComponent>();
         systemEntity->CreateComponent<StreamerComponent>();
         systemEntity->CreateComponent<StreamerComponent>();
         systemEntity->CreateComponent(AZ::Uuid("{CAE3A025-FAC9-4537-B39E-0A800A2326DF}")); // JobManager component
         systemEntity->CreateComponent(AZ::Uuid("{CAE3A025-FAC9-4537-B39E-0A800A2326DF}")); // JobManager component
         systemEntity->CreateComponent(AZ::Uuid("{D5A73BCC-0098-4d1e-8FE4-C86101E374AC}")); // AssetDatabase component
         systemEntity->CreateComponent(AZ::Uuid("{D5A73BCC-0098-4d1e-8FE4-C86101E374AC}")); // AssetDatabase component
@@ -175,9 +173,7 @@ namespace UnitTest
         ComponentApplication componentApp;
         ComponentApplication componentApp;
         ComponentApplication::Descriptor desc;
         ComponentApplication::Descriptor desc;
         desc.m_useExistingAllocator = true;
         desc.m_useExistingAllocator = true;
-        ComponentApplication::StartupParameters startupParams;
-        startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
-        Entity* systemEntity = componentApp.Create(desc, startupParams);
+        Entity* systemEntity = componentApp.Create(desc, {});
         AZ_TEST_ASSERT(systemEntity);
         AZ_TEST_ASSERT(systemEntity);
         systemEntity->Init();
         systemEntity->Init();
 
 
@@ -631,10 +627,7 @@ namespace UnitTest
             ComponentApplication::Descriptor desc;
             ComponentApplication::Descriptor desc;
             desc.m_useExistingAllocator = true;
             desc.m_useExistingAllocator = true;
 
 
-            ComponentApplication::StartupParameters startupParams;
-            startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
-
-            Entity* systemEntity = m_componentApp->Create(desc, startupParams);
+            Entity* systemEntity = m_componentApp->Create(desc, {});
             systemEntity->Init();
             systemEntity->Init();
 
 
             m_entity = aznew Entity();
             m_entity = aznew Entity();
@@ -1116,7 +1109,6 @@ namespace UnitTest
         app.UserSettingsFileLocatorBus::Handler::BusConnect();
         app.UserSettingsFileLocatorBus::Handler::BusConnect();
 
 
         MyUserSettings::Reflect(app.GetSerializeContext());
         MyUserSettings::Reflect(app.GetSerializeContext());
-        systemEntity->CreateComponent<MemoryComponent>();
 
 
         UserSettingsComponent* globalUserSettingsComponent = systemEntity->CreateComponent<UserSettingsComponent>();
         UserSettingsComponent* globalUserSettingsComponent = systemEntity->CreateComponent<UserSettingsComponent>();
         AZ_TEST_ASSERT(globalUserSettingsComponent);
         AZ_TEST_ASSERT(globalUserSettingsComponent);
@@ -1978,10 +1970,7 @@ namespace Benchmark
         ComponentApplication::Descriptor desc;
         ComponentApplication::Descriptor desc;
         desc.m_useExistingAllocator = true;
         desc.m_useExistingAllocator = true;
 
 
-        ComponentApplication::StartupParameters startupParams;
-        startupParams.m_allocator = &AZ::AllocatorInstance<AZ::SystemAllocator>::Get();
-
-        Entity* systemEntity = componentApp.Create(desc, startupParams);
+        Entity* systemEntity = componentApp.Create(desc, {});
         systemEntity->Init();
         systemEntity->Init();
 
 
         while(state.KeepRunning())
         while(state.KeepRunning())

+ 0 - 2
Code/Framework/AzCore/Tests/DOM/DomFixtures.cpp

@@ -16,12 +16,10 @@ namespace AZ::Dom::Tests
     void DomTestHarness::SetUpHarness()
     void DomTestHarness::SetUpHarness()
     {
     {
         NameDictionary::Create();
         NameDictionary::Create();
-        AZ::AllocatorInstance<ValueAllocator>::Create();
     }
     }
 
 
     void DomTestHarness::TearDownHarness()
     void DomTestHarness::TearDownHarness()
     {
     {
-        AZ::AllocatorInstance<ValueAllocator>::Destroy();
         NameDictionary::Destroy();
         NameDictionary::Destroy();
     }
     }
 
 

+ 27 - 0
Code/Framework/AzCore/Tests/Debug/PerformanceCollectorTests.cpp

@@ -187,4 +187,31 @@ namespace UnitTest
         }
         }
     }
     }
 
 
+    TEST_F(PerformanceCollectorTest, CreatePerformnaceCollector_WithDefaultFileExtension_ValidateFileExtension)
+    {
+        auto paramList = AZStd::to_array<AZStd::string_view>({ "param1" });
+        auto onCompleteCallback = [](AZ::u32)
+        {
+        };
+
+        AZ::Debug::PerformanceCollector performanceCollector("PerformanceCollectorTest", paramList, onCompleteCallback);
+
+        const AZStd::string& actualExtension = performanceCollector.GetFileExtension();
+        ASSERT_EQ("json", actualExtension);
+    }
+
+    TEST_F(PerformanceCollectorTest, CreatePerformanceCollector_WithCustomFileExtension_ValidateFileExtension)
+    {
+        auto paramList = AZStd::to_array<AZStd::string_view>({ "param1" });
+        auto onCompleteCallback = [](AZ::u32)
+        {
+        };
+        const AZStd::string testFileExtention("test.json");
+
+        AZ::Debug::PerformanceCollector performanceCollector("PerformanceCollectorTest", paramList, onCompleteCallback, testFileExtention);
+
+        const AZStd::string& actualExtension = performanceCollector.GetFileExtension();
+        ASSERT_EQ(testFileExtention, actualExtension);
+    }
+
 }//namespace UnitTest
 }//namespace UnitTest

+ 0 - 4
Code/Framework/AzCore/Tests/EBus.cpp

@@ -1763,8 +1763,6 @@ namespace UnitTest
         using namespace QueueMessageTest;
         using namespace QueueMessageTest;
 
 
         // Setup
         // Setup
-        AllocatorInstance<PoolAllocator>::Create();
-        AllocatorInstance<ThreadPoolAllocator>::Create();
         JobManagerDesc jobDesc;
         JobManagerDesc jobDesc;
         JobManagerThreadDesc threadDesc;
         JobManagerThreadDesc threadDesc;
         jobDesc.m_workerThreads.push_back(threadDesc);
         jobDesc.m_workerThreads.push_back(threadDesc);
@@ -1818,8 +1816,6 @@ namespace UnitTest
         JobContext::SetGlobalContext(nullptr);
         JobContext::SetGlobalContext(nullptr);
         delete m_jobContext;
         delete m_jobContext;
         delete m_jobManager;
         delete m_jobManager;
-        AllocatorInstance<ThreadPoolAllocator>::Destroy();
-        AllocatorInstance<PoolAllocator>::Destroy();
     }
     }
 
 
     class QueueEbusTest
     class QueueEbusTest

+ 0 - 12
Code/Framework/AzCore/Tests/Jobs.cpp

@@ -78,9 +78,6 @@ namespace UnitTest
         {
         {
             LeakDetectionFixture::SetUp();
             LeakDetectionFixture::SetUp();
 
 
-            AllocatorInstance<PoolAllocator>::Create();
-            AllocatorInstance<ThreadPoolAllocator>::Create();
-
             JobManagerDesc desc;
             JobManagerDesc desc;
             JobManagerThreadDesc threadDesc;
             JobManagerThreadDesc threadDesc;
 #if AZ_TRAIT_SET_JOB_PROCESSOR_ID
 #if AZ_TRAIT_SET_JOB_PROCESSOR_ID
@@ -113,9 +110,6 @@ namespace UnitTest
             delete m_jobContext;
             delete m_jobContext;
             delete m_jobManager;
             delete m_jobManager;
 
 
-            AllocatorInstance<ThreadPoolAllocator>::Destroy();
-            AllocatorInstance<PoolAllocator>::Destroy();
-
             LeakDetectionFixture::TearDown();
             LeakDetectionFixture::TearDown();
         }
         }
     };
     };
@@ -1608,9 +1602,6 @@ namespace Benchmark
 
 
         void internalSetUp()
         void internalSetUp()
         {
         {
-            AllocatorInstance<PoolAllocator>::Create();
-            AllocatorInstance<ThreadPoolAllocator>::Create();
-
             JobManagerDesc desc;
             JobManagerDesc desc;
             JobManagerThreadDesc threadDesc;
             JobManagerThreadDesc threadDesc;
 #if AZ_TRAIT_SET_JOB_PROCESSOR_ID
 #if AZ_TRAIT_SET_JOB_PROCESSOR_ID
@@ -1669,9 +1660,6 @@ namespace Benchmark
             m_randomDepths = {};
             m_randomDepths = {};
             delete m_jobContext;
             delete m_jobContext;
             delete m_jobManager;
             delete m_jobManager;
-
-            AllocatorInstance<ThreadPoolAllocator>::Destroy();
-            AllocatorInstance<PoolAllocator>::Destroy();
         }
         }
         void TearDown(::benchmark::State&) override
         void TearDown(::benchmark::State&) override
         {
         {

+ 0 - 72
Code/Framework/AzCore/Tests/Memory.cpp

@@ -119,8 +119,6 @@ namespace UnitTest
             // On windows we don't require to preallocate memory to function.
             // On windows we don't require to preallocate memory to function.
             // On most consoles we do!
             // On most consoles we do!
             {
             {
-                AllocatorInstance<SystemAllocator>::Create();
-
                 IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
                 IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
 
 
                 for (int i = 0; i < 100; ++i)
                 for (int i = 0; i < 100; ++i)
@@ -154,14 +152,10 @@ namespace UnitTest
                         m_threads[i].join();
                         m_threads[i].join();
                     }
                     }
                 }
                 }
-                //////////////////////////////////////////////////////////////////////////
-
-                AllocatorInstance<SystemAllocator>::Destroy();
             }
             }
 #endif
 #endif
             memset(address, 0, AZ_ARRAY_SIZE(address) * sizeof(void*));
             memset(address, 0, AZ_ARRAY_SIZE(address) * sizeof(void*));
 
 
-            AllocatorInstance<SystemAllocator>::Create();
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
 
 
             for (int i = 0; i < 100; ++i)
             for (int i = 0; i < 100; ++i)
@@ -287,8 +281,6 @@ namespace UnitTest
             //AZStd::chrono::microseconds exTime = AZStd::chrono::steady_clock::now() - startTime;
             //AZStd::chrono::microseconds exTime = AZStd::chrono::steady_clock::now() - startTime;
             //AZ_Printf("UnitTest::SystemAllocatorTest::mspaces","Time: %d Ms\n",exTime.count());
             //AZ_Printf("UnitTest::SystemAllocatorTest::mspaces","Time: %d Ms\n",exTime.count());
             //////////////////////////////////////////////////////////////////////////
             //////////////////////////////////////////////////////////////////////////
-
-            AllocatorInstance<SystemAllocator>::Destroy();
         }
         }
     };
     };
 
 
@@ -302,21 +294,6 @@ namespace UnitTest
     {
     {
     protected:
     protected:
     public:
     public:
-        void SetUp() override
-        {
-            MemoryTrackingFixture::SetUp();
-
-            AllocatorInstance<SystemAllocator>::Create();
-            AllocatorInstance<PoolAllocator>::Create();
-        }
-
-        void TearDown() override
-        {
-            AllocatorInstance<PoolAllocator>::Destroy();
-            AllocatorInstance<SystemAllocator>::Destroy();
-            MemoryTrackingFixture::TearDown();
-        }
-
         void run()
         void run()
         {
         {
             IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
             IAllocator& poolAllocator = AllocatorInstance<PoolAllocator>::Get();
@@ -456,17 +433,6 @@ namespace UnitTest
             {
             {
                 m_desc[i].m_stackSize = m_threadStackSize;
                 m_desc[i].m_stackSize = m_threadStackSize;
             }
             }
-
-            AllocatorInstance<SystemAllocator>::Create();
-            AllocatorInstance<ThreadPoolAllocator>::Create();
-        }
-
-        void TearDown() override
-        {
-            AllocatorInstance<ThreadPoolAllocator>::Destroy();
-            AllocatorInstance<SystemAllocator>::Destroy();
-
-            MemoryTrackingFixture::TearDown();
         }
         }
 
 
         void AllocDeallocFunc()
         void AllocDeallocFunc()
@@ -683,9 +649,6 @@ namespace UnitTest
             }
             }
             //////////////////////////////////////////////////////////////////////////
             //////////////////////////////////////////////////////////////////////////
 
 
-            // Our pools will support only 512 byte allocations
-            AZ::AllocatorInstance<MyThreadPoolAllocator>::Create();
-
             void* pooled512 = AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().Allocate(512, 512);
             void* pooled512 = AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().Allocate(512, 512);
             ASSERT_TRUE(pooled512);
             ASSERT_TRUE(pooled512);
             AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().DeAllocate(pooled512);
             AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().DeAllocate(pooled512);
@@ -694,8 +657,6 @@ namespace UnitTest
             void* pooled2048 = AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().Allocate(2048, 2048);
             void* pooled2048 = AZ::AllocatorInstance<MyThreadPoolAllocator>::Get().Allocate(2048, 2048);
             (void)pooled2048;
             (void)pooled2048;
             AZ_TEST_STOP_TRACE_SUPPRESSION(1);
             AZ_TEST_STOP_TRACE_SUPPRESSION(1);
-
-            AZ::AllocatorInstance<MyThreadPoolAllocator>::Destroy();
         }
         }
     };
     };
 
 
@@ -711,21 +672,6 @@ namespace UnitTest
         : public MemoryTrackingFixture
         : public MemoryTrackingFixture
     {
     {
     public:
     public:
-        void SetUp() override
-        {
-            MemoryTrackingFixture::SetUp();
-
-            AllocatorInstance<SystemAllocator>::Create();
-            AllocatorInstance<PoolAllocator>::Create();
-        }
-
-        void TearDown() override
-        {
-            AllocatorInstance<PoolAllocator>::Destroy();
-            AllocatorInstance<SystemAllocator>::Destroy();
-            MemoryTrackingFixture::TearDown();
-        }
-
         void run()
         void run()
         {
         {
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
@@ -813,22 +759,6 @@ namespace UnitTest
             MyDerivedClass() = default;
             MyDerivedClass() = default;
         };
         };
     public:
     public:
-        void SetUp() override
-        {
-            MemoryTrackingFixture::SetUp();
-
-            AllocatorInstance<SystemAllocator>::Create();
-            AllocatorInstance<PoolAllocator>::Create();
-        }
-
-        void TearDown() override
-        {
-            AllocatorInstance<PoolAllocator>::Destroy();
-            AllocatorInstance<SystemAllocator>::Destroy();
-
-            MemoryTrackingFixture::TearDown();
-        }
-
         void run()
         void run()
         {
         {
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
             IAllocator& sysAllocator = AllocatorInstance<SystemAllocator>::Get();
@@ -940,7 +870,6 @@ namespace UnitTest
     public:
     public:
         void SetUp() override
         void SetUp() override
         {
         {
-            AllocatorInstance<SystemAllocator>::Create();
             tr = (test_record*)AZ_OS_MALLOC(sizeof(test_record)*N, 8);
             tr = (test_record*)AZ_OS_MALLOC(sizeof(test_record)*N, 8);
             MAX_SIZE = 4096;
             MAX_SIZE = 4096;
         }
         }
@@ -948,7 +877,6 @@ namespace UnitTest
         void TearDown() override
         void TearDown() override
         {
         {
             AZ_OS_FREE(tr);
             AZ_OS_FREE(tr);
-            AllocatorInstance<SystemAllocator>::Destroy();
         }
         }
 
 
         //////////////////////////////////////////////////////////////////////////
         //////////////////////////////////////////////////////////////////////////

+ 28 - 166
Code/Framework/AzCore/Tests/Memory/AllocatorBenchmarks.cpp

@@ -30,126 +30,13 @@ namespace Benchmark
         size_t GetMemorySize(void* memory);
         size_t GetMemorySize(void* memory);
     }
     }
 
 
-    /// <summary>
-    /// Test allocator wrapper that redirects the calls to the passed TAllocator by using AZ::AllocatorInstance.
-    /// It also creates/destroys the TAllocator type (to reflect what happens at runtime)
-    /// </summary>
-    /// <typeparam name="TAllocator">Allocator type to wrap</typeparam>
-    template<typename TAllocator>
-    class TestAllocatorWrapper
+    class RawMallocAllocator
+        : public AZStd::stateless_allocator
     {
     {
     public:
     public:
-        static void SetUp()
-        {
-            AZ::AllocatorInstance<TAllocator>::Create();
-        }
-
-        static void TearDown()
-        {
-            AZ::AllocatorInstance<TAllocator>::Destroy();
-        }
-
-        static void* Allocate(size_t byteSize, size_t alignment)
-        {
-            return AZ::AllocatorInstance<TAllocator>::Get().Allocate(byteSize, alignment);
-        }
-
-        static void DeAllocate(void* ptr, size_t byteSize = 0)
-        {
-            AZ::AllocatorInstance<TAllocator>::Get().DeAllocate(ptr, byteSize);
-        }
-
-        static void* ReAllocate(void* ptr, size_t newSize, size_t newAlignment)
-        {
-            return AZ::AllocatorInstance<TAllocator>::Get().ReAllocate(ptr, newSize, newAlignment);
-        }
-
-        static void GarbageCollect()
-        {
-            AZ::AllocatorInstance<TAllocator>::Get().GarbageCollect();
-        }
-
-        static size_t NumAllocatedBytes()
-        {
-            return AZ::AllocatorInstance<TAllocator>::Get().NumAllocatedBytes() +
-                AZ::AllocatorInstance<TAllocator>::Get().GetUnAllocatedMemory();
-        }
-
-        static size_t GetSize(void* ptr)
-        {
-            return AZ::AllocatorInstance<TAllocator>::Get().AllocationSize(ptr);
-        }
+        void GarbageCollect() {}
+        size_t NumAllocatedBytes() { return 0; }
     };
     };
-
-    /// <summary>
-    /// Basic allocator used as a baseline. This allocator is the most basic allocation possible with the OS (AZ_OS_MALLOC).
-    /// </summary>
-    class RawMallocAllocator {};
-
-    template<>
-    class TestAllocatorWrapper<RawMallocAllocator>
-    {
-    public:
-        TestAllocatorWrapper()
-        {
-            s_numAllocatedBytes = 0;
-        }
-
-        static void SetUp()
-        {
-            s_numAllocatedBytes = 0;
-        }
-
-        static void TearDown()
-        {
-        }
-
-        static void* Allocate(size_t byteSize, size_t)
-        {
-            s_numAllocatedBytes += byteSize;
-            // Don't pass an alignment since we wont be able to get the memory size without also passing the alignment
-            return AZ_OS_MALLOC(byteSize, 1);
-        }
-
-        static void DeAllocate(void* ptr, size_t = 0)
-        {
-            s_numAllocatedBytes -= Platform::GetMemorySize(ptr);
-            AZ_OS_FREE(ptr);
-        }
-
-        static void* ReAllocate(void* ptr, size_t newSize, size_t)
-        {
-            s_numAllocatedBytes -= Platform::GetMemorySize(ptr);
-            AZ_OS_FREE(ptr);
-
-            s_numAllocatedBytes += newSize;
-            return AZ_OS_MALLOC(newSize, 1);
-        }
-
-        static size_t Resize(void* ptr, size_t newSize)
-        {
-            AZ_UNUSED(ptr);
-            AZ_UNUSED(newSize);
-
-            return 0;
-        }
-
-        static void GarbageCollect() {}
-
-        static size_t NumAllocatedBytes()
-        {
-            return s_numAllocatedBytes;
-        }
-
-        static size_t GetSize(void* ptr)
-        {
-            return Platform::GetMemorySize(ptr);
-        }
-
-    private:
-         inline static size_t s_numAllocatedBytes = 0;
-    };
-
     // We use both this HphaSchemaAllocator and the SystemAllocator configured with Hpha because the SystemAllocator
     // We use both this HphaSchemaAllocator and the SystemAllocator configured with Hpha because the SystemAllocator
     // has extra things
     // has extra things
     class HphaSchemaAllocator : public AZ::SimpleSchemaAllocator<AZ::HphaSchema>
     class HphaSchemaAllocator : public AZ::SimpleSchemaAllocator<AZ::HphaSchema>
@@ -199,14 +86,12 @@ namespace Benchmark
         : public ::benchmark::Fixture
         : public ::benchmark::Fixture
     {
     {
     protected:
     protected:
-        using TestAllocatorType = TestAllocatorWrapper<TAllocator>;
+        using TestAllocatorType = TAllocator;
 
 
         virtual void internalSetUp(const ::benchmark::State& state)
         virtual void internalSetUp(const ::benchmark::State& state)
         {
         {
             if (state.thread_index() == 0)
             if (state.thread_index() == 0)
             {
             {
-                TestAllocatorType::SetUp();
-
                 m_allocations.resize(state.threads());
                 m_allocations.resize(state.threads());
                 for (auto& perThreadAllocations : m_allocations)
                 for (auto& perThreadAllocations : m_allocations)
                 {
                 {
@@ -221,8 +106,6 @@ namespace Benchmark
             {
             {
                 m_allocations.clear();
                 m_allocations.clear();
                 m_allocations.shrink_to_fit();
                 m_allocations.shrink_to_fit();
-
-                TestAllocatorType::TearDown();
             }
             }
         }
         }
 
 
@@ -250,7 +133,11 @@ namespace Benchmark
             internalTearDown(state);
             internalTearDown(state);
         }
         }
 
 
+        const TestAllocatorType& GetAllocator() const { return m_allocator; }
+        TestAllocatorType& GetAllocator() { return m_allocator; }
+
     private:
     private:
+        TestAllocatorType m_allocator;
         AZStd::vector<AZStd::vector<void*>> m_allocations;
         AZStd::vector<AZStd::vector<void*>> m_allocations;
     };
     };
 
 
@@ -278,21 +165,21 @@ namespace Benchmark
                     totalAllocationSize += allocationSize;
                     totalAllocationSize += allocationSize;
 
 
                     state.ResumeTiming();
                     state.ResumeTiming();
-                    perThreadAllocations[allocationIndex] = TestAllocatorType::Allocate(allocationSize, 0);
+                    perThreadAllocations[allocationIndex] = this->GetAllocator().allocate(allocationSize, 0);
                     state.PauseTiming();
                     state.PauseTiming();
                 }
                 }
 
 
-                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(TestAllocatorType::NumAllocatedBytes()), benchmark::Counter::kDefaults);
+                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(this->GetAllocator().NumAllocatedBytes()), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
 
 
                 for (size_t allocationIndex = 0; allocationIndex < numberOfAllocations; ++allocationIndex)
                 for (size_t allocationIndex = 0; allocationIndex < numberOfAllocations; ++allocationIndex)
                 {
                 {
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
-                    TestAllocatorType::DeAllocate(perThreadAllocations[allocationIndex], allocationSize);
+                    this->GetAllocator().deallocate(perThreadAllocations[allocationIndex], allocationSize);
                     perThreadAllocations[allocationIndex] = nullptr;
                     perThreadAllocations[allocationIndex] = nullptr;
                 }
                 }
-                TestAllocatorType::GarbageCollect();
+                this->GetAllocator().GarbageCollect();
 
 
                 state.SetItemsProcessed(numberOfAllocations);
                 state.SetItemsProcessed(numberOfAllocations);
 
 
@@ -323,7 +210,7 @@ namespace Benchmark
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
                     totalAllocationSize += allocationSize;
                     totalAllocationSize += allocationSize;
-                    perThreadAllocations[allocationIndex] = TestAllocatorType::Allocate(allocationSize, 0);
+                    perThreadAllocations[allocationIndex] = this->GetAllocator().allocate(allocationSize, 0);
                 }
                 }
 
 
                 for (size_t allocationIndex = 0; allocationIndex < numberOfAllocations; ++allocationIndex)
                 for (size_t allocationIndex = 0; allocationIndex < numberOfAllocations; ++allocationIndex)
@@ -331,17 +218,17 @@ namespace Benchmark
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const AllocationSizeArray& allocationArray = s_allocationSizes[TAllocationSize];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
                     const size_t allocationSize = allocationArray[allocationIndex % allocationArray.size()];
                     state.ResumeTiming();
                     state.ResumeTiming();
-                    TestAllocatorType::DeAllocate(perThreadAllocations[allocationIndex], allocationSize);
+                    this->GetAllocator().deallocate(perThreadAllocations[allocationIndex], allocationSize);
                     state.PauseTiming();
                     state.PauseTiming();
                     perThreadAllocations[allocationIndex] = nullptr;
                     perThreadAllocations[allocationIndex] = nullptr;
                 }
                 }
 
 
-                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(TestAllocatorType::NumAllocatedBytes()), benchmark::Counter::kDefaults);
+                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(this->GetAllocator().NumAllocatedBytes()), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
 
 
                 state.SetItemsProcessed(numberOfAllocations);
                 state.SetItemsProcessed(numberOfAllocations);
 
 
-                TestAllocatorType::GarbageCollect();
+                this->GetAllocator().GarbageCollect();
 
 
                 state.ResumeTiming();
                 state.ResumeTiming();
             }
             }
@@ -351,17 +238,7 @@ namespace Benchmark
     template<typename TAllocator>
     template<typename TAllocator>
     class RecordedAllocationBenchmarkFixture : public ::benchmark::Fixture
     class RecordedAllocationBenchmarkFixture : public ::benchmark::Fixture
     {
     {
-        using TestAllocatorType = TestAllocatorWrapper<TAllocator>;
-
-        virtual void internalSetUp()
-        {
-            TestAllocatorType::SetUp();
-        }
-
-        void internalTearDown()
-        {
-            TestAllocatorType::TearDown();
-        }
+        using TestAllocatorType = TAllocator;
 
 
         #pragma pack(push, 1)
         #pragma pack(push, 1)
         struct alignas(1) AllocatorOperation
         struct alignas(1) AllocatorOperation
@@ -380,24 +257,6 @@ namespace Benchmark
         static_assert(sizeof(AllocatorOperation) == 8);
         static_assert(sizeof(AllocatorOperation) == 8);
 
 
     public:
     public:
-        void SetUp(const ::benchmark::State&) override
-        {
-            internalSetUp();
-        }
-        void SetUp(::benchmark::State&) override
-        {
-            internalSetUp();
-        }
-
-        void TearDown(const ::benchmark::State&) override
-        {
-            internalTearDown();
-        }
-        void TearDown(::benchmark::State&) override
-        {
-            internalTearDown();
-        }
-
         void Benchmark(benchmark::State& state)
         void Benchmark(benchmark::State& state)
         {
         {
             for ([[maybe_unused]] auto _ : state)
             for ([[maybe_unused]] auto _ : state)
@@ -436,7 +295,7 @@ namespace Benchmark
                                 if (it.second) // otherwise already allocated
                                 if (it.second) // otherwise already allocated
                                 {
                                 {
                                     state.ResumeTiming();
                                     state.ResumeTiming();
-                                    void* ptr = TestAllocatorType::Allocate(operation.m_size, operation.m_alignment);
+                                    void* ptr = this->GetAllocator().allocate(operation.m_size, operation.m_alignment);
                                     state.PauseTiming();
                                     state.PauseTiming();
                                     totalAllocationSize += operation.m_size;
                                     totalAllocationSize += operation.m_size;
                                     it.first->second = ptr;
                                     it.first->second = ptr;
@@ -446,7 +305,7 @@ namespace Benchmark
                                     // Doing a resize, dont account for this memory change, this operation is rare and we dont have
                                     // Doing a resize, dont account for this memory change, this operation is rare and we dont have
                                     // the size of the previous allocation
                                     // the size of the previous allocation
                                     state.ResumeTiming();
                                     state.ResumeTiming();
-                                    TestAllocatorType::ReAllocate(it.first->second, operation.m_size, operation.m_alignment);
+                                    this->GetAllocator().reallocate(it.first->second, operation.m_size, operation.m_alignment);
                                     state.PauseTiming();
                                     state.PauseTiming();
                                 }
                                 }
                             }
                             }
@@ -459,7 +318,7 @@ namespace Benchmark
                                     {
                                     {
                                         totalAllocationSize -= operation.m_size;
                                         totalAllocationSize -= operation.m_size;
                                         state.ResumeTiming();
                                         state.ResumeTiming();
-                                        TestAllocatorType::DeAllocate(
+                                        this->GetAllocator().deallocate(
                                             ptrIt->second,
                                             ptrIt->second,
                                             /*operation.m_size*/ 0); // size is not correct after a resize, a 0 size deals with it
                                             /*operation.m_size*/ 0); // size is not correct after a resize, a 0 size deals with it
                                         state.PauseTiming();
                                         state.PauseTiming();
@@ -470,7 +329,7 @@ namespace Benchmark
                                 {
                                 {
                                     // Just to account of the call of deallocate(nullptr);
                                     // Just to account of the call of deallocate(nullptr);
                                     state.ResumeTiming();
                                     state.ResumeTiming();
-                                    TestAllocatorType::DeAllocate(nullptr, /*operation.m_size*/ 0);
+                                    this->GetAllocator().deallocate(nullptr, /*operation.m_size*/ 0);
                                     state.PauseTiming();
                                     state.PauseTiming();
                                 }
                                 }
                             }
                             }
@@ -486,23 +345,26 @@ namespace Benchmark
                     for (const auto& pointerMapping : pointerRemapping)
                     for (const auto& pointerMapping : pointerRemapping)
                     {
                     {
                         state.ResumeTiming();
                         state.ResumeTiming();
-                        TestAllocatorType::DeAllocate(pointerMapping.second);
+                        this->GetAllocator().deallocate(pointerMapping.second);
                         state.PauseTiming();
                         state.PauseTiming();
                     }
                     }
                     itemsProcessed += pointerRemapping.size();
                     itemsProcessed += pointerRemapping.size();
                     pointerRemapping.clear();
                     pointerRemapping.clear();
                 }
                 }
 
 
-                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(TestAllocatorType::NumAllocatedBytes()), benchmark::Counter::kDefaults);
+                state.counters[s_counterAllocatorMemory] = benchmark::Counter(static_cast<double>(this->GetAllocator().NumAllocatedBytes()), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
                 state.counters[s_counterBenchmarkMemory] = benchmark::Counter(static_cast<double>(totalAllocationSize), benchmark::Counter::kDefaults);
 
 
                 state.SetItemsProcessed(itemsProcessed);
                 state.SetItemsProcessed(itemsProcessed);
 
 
-                TestAllocatorType::GarbageCollect();
+                this->GetAllocator().GarbageCollect();
 
 
                 state.ResumeTiming();
                 state.ResumeTiming();
             }
             }
         }
         }
+    private:
+        TestAllocatorType m_allocator;
+        TestAllocatorType& GetAllocator() { return m_allocator; }
     };
     };
 
 
     // For non-threaded ranges, run 100, 400, 1600 amounts
     // For non-threaded ranges, run 100, 400, 1600 amounts

+ 0 - 10
Code/Framework/AzCore/Tests/Memory/HphaAllocator.cpp

@@ -56,16 +56,6 @@ namespace UnitTest
         : public LeakDetectionFixture
         : public LeakDetectionFixture
         , public ::testing::WithParamInterface<HphaSchemaTestParameters>
         , public ::testing::WithParamInterface<HphaSchemaTestParameters>
     {
     {
-    public:
-        void SetUp() override
-        {
-            AZ::AllocatorInstance<HphaSchema_TestAllocator>::Create();
-        }
-
-        void TearDown() override
-        {
-            AZ::AllocatorInstance<HphaSchema_TestAllocator>::Destroy();
-        }
     };
     };
 
 
     TEST_P(HphaSchemaTestFixture, Allocate)
     TEST_P(HphaSchemaTestFixture, Allocate)

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä